Is there a simple way of replacing all negative values in an array with 0?
I’m having a complete block on how to do it using a NumPy array.
E.g.
a = array([1, 2, 3, -4, 5])
I need to return
[1, 2, 3, 0, 5]
a < 0 gives:
[False, False, False, True, False]
This is where I’m stuck – how to use this array to modify the original array.
Answers:
Thank you for visiting the Q&A section on Magenaut. Please note that all the answers may not help you solve the issue immediately. So please treat them as advisements. If you found the post helpful (or not), leave a comment & I’ll get back to you as soon as possible.
Method 1
You are halfway there. Try:
In [4]: a[a < 0] = 0 In [5]: a Out[5]: array([1, 2, 3, 0, 5])
Method 2
Try numpy.clip:
>>> import numpy
>>> a = numpy.arange(-10, 10)
>>> a
array([-10, -9, -8, -7, -6, -5, -4, -3, -2, -1, 0, 1, 2,
3, 4, 5, 6, 7, 8, 9])
>>> a.clip(0, 10)
array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
You can clip only the bottom half with clip(0).
>>> a = numpy.array([1, 2, 3, -4, 5]) >>> a.clip(0) array([1, 2, 3, 0, 5])
You can clip only the top half with clip(max=n). (This is much better than my previous suggestion, which involved passing NaN to the first parameter and using out to coerce the type.):
>>> a.clip(max=2) array([ 1, 2, 2, -4, 2])
Another interesting approach is to use where:
>>> numpy.where(a <= 2, a, 2) array([ 1, 2, 2, -4, 2])
Finally, consider aix‘s answer. I prefer clip for simple operations because it’s self-documenting, but his answer is preferable for more complex operations.
Method 3
Another minimalist Python solution without using numpy:
[0 if i < 0 else i for i in a]
No need to define any extra functions.
a = [1, 2, 3, -4, -5.23, 6] [0 if i < 0 else i for i in a]
yields:
[1, 2, 3, 0, 0, 6]
Method 4
And yet another possibility:
In [2]: a = array([1, 2, 3, -4, 5]) In [3]: where(a<0, 0, a) Out[3]: array([1, 2, 3, 0, 5])
Method 5
Here’s a way to do it in Python without NumPy. Create a function that returns what you want and use a list comprehension, or the map function.
>>> a = [1, 2, 3, -4, 5] >>> def zero_if_negative(x): ... if x < 0: ... return 0 ... return x ... >>> [zero_if_negative(x) for x in a] [1, 2, 3, 0, 5] >>> map(zero_if_negative, a) [1, 2, 3, 0, 5]
Method 6
Benchmark using numpy:
%%timeit a = np.random.random(1000) - 0.5 b = np.maximum(a,0) # 18.2 µs ± 204 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)
%%timeit a = np.random.random(1000) - 0.5 a[a < 0] = 0 # 19.6 µs ± 304 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)
%%timeit a = np.random.random(1000) - 0.5 b = np.where(a<0, 0, a) # 21.1 µs ± 134 ns per loop (mean ± std. dev. of 7 runs, 10000 loops each)
%%timeit a = np.random.random(1000) - 0.5 b = a.clip(0) # 37.7 µs ± 124 ns per loop (mean ± std. dev. of 7 runs, 10000 loops each)
Supprisingly, np.maximum beat @NPE answer.
Caveat:
-
os[os < 0] = 0is faster thannp.where()but not supported bynumba. But whatever,np.maximum()is the fastest that I found. -
np.maximum()is different fromnp.max()andnp.amax().np.maximum()can comparevectorwith single value.
All methods was sourced from stackoverflow.com or stackexchange.com, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0