Reputation: 37
I'm attempting to apply a different function to the first and second part of a numpy array. So in this example, multiplying the terms less than 0.5 by 2 and adding 1 to the terms of 0.5 and above.
def myFunc:
x = numpy.linspace(0,1,11)
def test():
for i in x:
if i < 0.5:
a = i*2
else:
a = i+1.0
return(a)
print(test())
Which I want to return:
[0,0.2,0.4,0.6,0.8,1.5,1.6,1.7,1.8,1.9,2]
Thank You.
Upvotes: 1
Views: 674
Reputation: 5774
This should do it:
x[x < 0.5] *= 2
x[x >= 0.5] +=1
If you want to stick with numpy
, this is highly preferable over list comprehensions.
Here is a short comparison using list comprehension and numpy
masking:
def myFunc_lc(x):
return np.asarray([i*2 if i < 0.5 else i+1 for i in x])
def myFunc_np(x):
x[x < 0.5] *= 2
x[x >= 0.5] +=1
return x
def myFunc_np2(x): # using a constant masking array
ma = x < 0.5
x[ma] *= 2
x[~ma] +=1
return x
x = np.linspace(0, 1, 11)
%timeit myFunc_np(x) # 6.62 µs ± 160 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)
%timeit myFunc_np2(x) # 6.24 µs ± 113 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)
%timeit myFunc_lc(x) # 6.75 µs ± 160 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)
%timeit np.select([x<0.5,x>=0.5],[x*2,x+1]) # 39.9 µs ± 1.78 µs per loop (mean ± std. dev. of 7 runs, 10000 loops each)
x = np.linspace(0, 1, 10000)
%timeit myFunc_np(x) # 43.4 µs ± 1.13 µs per loop (mean ± std. dev. of 7 runs, 10000 loops each)
%timeit myFunc_np2(x) # 43.8 µs ± 1.26 µs per loop (mean ± std. dev. of 7 runs, 10000 loops each)
%timeit myFunc_lc(x) # 3.7 ms ± 103 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
%timeit np.select([x<0.5,x>=0.5],[x*2,x+1]) # 79.2 µs ± 2.54 µs per loop (mean ± std. dev. of 7 runs, 10000 loops each)
I guess it is quite obvious why numpy
masking is better than list comprehension. Especially when using larger arrays, numpy
is alot faster.
Using small arrays, numpy is only slightly faster. np.select
is really slow for short arrays but quite ok for larger arrays. Creating a mask in myFunc_np2
is even faster for small arrays, but slightly slower for larger arrays.
Upvotes: 0
Reputation: 323266
If you want a numpy
solution , I will using select
np.select([x<0.5,x>=0.5],[x*2,x+1])
Out[905]: array([0. , 0.2, 0.4, 0.6, 0.8, 1.5, 1.6, 1.7, 1.8, 1.9, 2. ])
Upvotes: 1
Reputation: 51155
You could simply use a list comprehension:
[i*2 if i < 0.5 else i+1 for i in x]
Upvotes: 1