You are halfway there. Try:
In [4]: a[a < 0] = 0
In [5]: a
Out[5]: array([1, 2, 3, 0, 5])
Answer from NPE on Stack OverflowYou are halfway there. Try:
In [4]: a[a < 0] = 0
In [5]: a
Out[5]: array([1, 2, 3, 0, 5])
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.
python
In the function clip_data, modify any negative values
in data to be zero. Then return data.
import numpy as np
def clip_data(data):
# clip the data here
return data
python - How to transform negative elements to zero without a loop? - Stack Overflow
python - Replace numpy ndarry negative elements with 0 (zero) - Stack Overflow
python - Converting positive and negative values to a bitstring using numpy.clip - Stack Overflow
You can use np.clip for this, clipping between zero and infinity:
arr = np.array([[2, -7, 5], [-6, 2, 0], [1, -4, 2], [-2, 6, 8]])
np.clip(arr, a_min = 0, a_max = np.inf)
array([[2., 0., 5.],
[0., 2., 0.],
[1., 0., 2.],
[0., 6., 8.]])
Otherwise, you can use something like this (note this changes the array in place):
arr[arr <= 0] = 0
>>> arr
array([[2, 0, 5],
[0, 2, 0],
[1, 0, 2],
[0, 6, 8]])
You could use np.where() too:
arr = np.array([[2, -7, 5], [-6, 2, 0], [1, -4, 2], [-2, 6, 8]])
result = np.where(arr<0, 0, arr)
Output:
[[2 0 5]
[0 2 0]
[1 0 2]
[0 6 8]]
To map everything greater than 0 to 1 (and everything less to 0) you could use np. where:
In [25]: np.where(np.array([1,0.45,3,-1,-2]) > 0, 1, 0)
Out[25]: array([1, 1, 1, 0, 0])
or
In [29]: (np.array([1,0.45,3,-1,-2]) > 0).astype('i1')
Out[29]: array([1, 1, 1, 0, 0], dtype=int8)
Note that np.where is returning an array with dtype int32 (4-byte ints), while astype('i1') is returning an array with dtype int8 (1-byte ints).
If you wish to pack these binary values into a uint8, you could use np.packbits:
In [48]: x = np.array([1,0.45,3,-1,-2])
In [49]: np.packbits((x > 0).astype('i1'))
Out[49]: array([224], dtype=uint8)
In [50]: bin(224)
Out[50]: '0b11100000'
Or, as a string:
In [60]: np.packbits((x > 0).astype('i1')).tostring()
Out[60]: '\xe0'
In [62]: bin(0xe0)
Out[62]: '0b11100000'
In [21]: arr = np.array([1,0.45,3,-1,-2])
In [22]: np.ceil(arr.clip(0, 1))
Out[22]: array([ 1., 1., 1., 0., 0.])
First it really helps when you ask a question if you can post a working example that demonstrates your issue. Without that we're left to guess.
It seems that maybe you're using an array of arrays instead of a multidimensional array. For example:
import numpy as np
data = np.arange(3)
# Make an array of arrays
arrayOfArrays = np.empty(4, dtype=object)
arrayOfArrays.fill(data)
print arrayOfArrays
# [[0 1 2] [0 1 2] [0 1 2] [0 1 2]]
# Make a 2d array
array2d = np.empty((4, 3), dtype=int)
array2d[:] = data
print array2d
# [[0 1 2]
# [0 1 2]
# [0 1 2]
# [0 1 2]]
# You can clip an ndarray of any dimenssion
array2d.clip(1)
# But clipping an array of arrays gives the error you describe
arrayOfArrays.clip(1)
# ValueError
# Traceback (most recent call last) <module>()
# 17
# 18 # This will fail
#
# ---> 19 arrayOfArrays.clip(1)
#
# ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all()
If you are in fact using an array of arrays, an array with dtype object, than try using a multidimensional array instead. arrays of dtype object are prone to all types of issues, I generally try to avoid them. You can tell whether you're using an array with dtype object by checking the shape and dtype like bellow:
print array2d.dtype
print array2d.shape
# int32
# (4, 3)
print arrayOfArrays.dtype
print arrayOfArrays.shape
# object
# (4,)
Of course in this case you could just loop over the outer array and call clip on each of the inner arrays.
for i in range(len(arrayOfArrays)):
arrayOfArrays[i].clip(1)
Try just setting the negative values to zero:
a[a<0] = 0