tags:

views:

85

answers:

4

If I have an array like

a = np.array([2, 3, -1, -4, 3])

I want to set all the negative elements to zero: [2, 3, 0, 0, 3]. How to do it with numpy without an explicit for? I need to use the modified a in a computation, for example

c = a * b

where b is another array with the same length of the original a

Conclusion

import numpy as np
from time import time

a = np.random.uniform(-1, 1, 20000000)
t = time(); b = np.where(a>0, a, 0); print "1. ", time() - t
a = np.random.uniform(-1, 1, 20000000)
t = time(); b = a.clip(min=0); print "2. ", time() - t
a = np.random.uniform(-1, 1, 20000000)
t = time(); a[a < 0] = 0; print "3. ", time() - t
a = np.random.uniform(-1, 1, 20000000)
t = time(); a[np.where(a<0)] = 0; print "4. ", time() - t
a = np.random.uniform(-1, 1, 20000000)
t = time(); b = [max(x, 0) for x in a]; print "5. ", time() - t
  1. 1.38629984856
  2. 0.516846179962 <- faster a.clip(min=0);
  3. 0.615426063538
  4. 0.944557905197
  5. 51.7364809513
+1  A: 

Does map do what you need it to?

b = map(lambda x: max(x, 0), a) # b == [2, 3, 0, 0, 3]

You can also get there with this list comprehension:

b = [max(x, 0) for x in a]
g.d.d.c
too slow ......
wiso
+5  A: 
a = a.clip(min=0)
wiso
better solution?
wiso
It might be. You'll have to test them to see which is fastest. I don't use numpy a lot, so I'm not sure, though numpy is supposed to be very well optimized, so it could well outperform my answers.
g.d.d.c
wiso, I think you found the fastest way.`%timeit a.clip(min=0,out=a)` took 5.65 microseconds per loop.`%timeit np.where(a>0,a,0)` took 24 microseconds per loop,`%timeit a[a<0]=0` took 11.6 microseconds per loop.
unutbu
+2  A: 

I would do this:

a[a < 0] = 0

If you want to keep the original a and only set the negative elements to zero in a copy, you can copy the array first:

c = a.copy()
c[c < 0] = 0
David Zaslavsky
+2  A: 

Use where

a[numpy.where(a<0)] = 0
Adam Schmideg