Reputation: 235
I need to optimize my code and have been able to remove for loops almost everywhere but struggle for this small part. I've looked at numpy.where but don't think I can use that but I'm not quite sure. If anyone knows which functions I should look at to optimize this part that would be greatly appreciated. This is used quite often and for loops are very slow in pyton so i need to do some optimization.
def f(x):
return np.pi * x * np.cos((np.pi / 2) * x ** 2)
x_samples = np.random.uniform(low=0.0, high=1.0, size=500000)
y_samples = np.random.uniform(low=0.0, high=1.0, size=500000) * 1.61
y_functie = f(x_samples)
y_hit, x_hit, x_miss, y_miss = [], [], [], []
for n in range(len(x_samples)):
if y_samples[n] <= y_functie[n]:
x_hit.append(x_samples[n]), y_hit.append(y_samples[n])
else:
x_miss.append(x_samples[n]), y_miss.append(y_samples[n])
Upvotes: 0
Views: 61
Reputation: 3862
By doing indexing you could do something like this:
import numpy as np
def f(x):
return np.pi * x * np.cos((np.pi / 2) * x ** 2)
x_samples = np.random.uniform(low=0.0, high=1.0, size=500000)
y_samples = np.random.uniform(low=0.0, high=1.0, size=500000) * 1.61
y_functie = f(x_samples)
def test1():
y_hit, x_hit, x_miss, y_miss = [], [], [], []
for n in range(len(x_samples)):
if y_samples[n] <= y_functie[n]:
x_hit.append(x_samples[n]), y_hit.append(y_samples[n])
else:
x_miss.append(x_samples[n]), y_miss.append(y_samples[n])
def test2():
x_hit = x_samples[y_samples<=y_functie]
x_miss = x_samples[y_samples>y_functie]
y_hit = y_samples[y_samples<=y_functie]
y_miss = y_samples[y_samples>y_functie]
test1()
test2()
With your test data I get timing differences of 700ms for test1
and 21ms for test2
. Of course you could simplify more by using only one boolean table and do everything in one go.
Depending on what you want to optimize for (speed or memory footprint) you could precalculate the boolean table with
hit_test = y_samples<=y_functie
Upvotes: 1
Reputation: 2367
You can use logical masking with the fancy indexing
to achieve the desired outcome:
import numpy as np
def f(x):
return np.pi * x * np.cos((np.pi / 2) * x ** 2)
x_samples = np.random.uniform(low=0.0, high=1.0, size=500000)
y_samples = np.random.uniform(low=0.0, high=1.0, size=500000) * 1.61
y_functie = f(x_samples)
hits = y_samples <= y_functie
misses = y_samples > y_functie
y_hit, x_hit, x_miss, y_miss = x_samples[hits], y_samples[hits], x_samples[misses], y_samples[misses]
Cheers.
Upvotes: 0