I have a 2D array in python with numbers ranging from positive values to negative ones. However I need to set an 'if' statement that says something like: if an element of the 2D array is negative (less than zero) set the value to zero.
Here's a snippet of the code I've used:
final_array = np.random.randint(-1,1, size=(4,4))
for i in final_array:
if final_array[i] < 0:
final_array[i] == 0
When running this code I get the error: IndexError: arrays used as indices must be of integer (or boolean) type
Any help would be massively appreciated
CodePudding user response:
You can set the value of elements in a Numpy array using conditions. For example, the code below sets every element less than 0 equal to 0.
final_array[final_array<0] = 0
CodePudding user response:
With your code I get a different error:
In [91]: final_array = np.random.randint(-1,1, size=(4,4))
...:
...: for i in final_array:
...: if final_array[i] < 0:
...: final_array[i] == 0
...:
Traceback (most recent call last):
Input In [91] in <cell line: 3>
if final_array[i] < 0:
ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all()
In [92]: final_array
Out[92]:
array([[ 0, 0, -1, 0],
[-1, -1, 0, 0],
[ 0, 0, 0, -1],
[ 0, -1, 0, 0]])
In [93]: i
Out[93]: array([ 0, 0, -1, 0])
In [94]: final_array[i]
Out[94]:
array([[ 0, 0, -1, 0],
[ 0, 0, -1, 0],
[ 0, -1, 0, 0],
[ 0, 0, -1, 0]])
Notice that i
is a row of final_array
. While it works in this case, it doesn't make sense to use it as an index, does it? It seems that you haven't read enough basic Python to do a simple iteration correctly.
For example with a list (of lists):
In [95]: alist = [[1],[3,4]]
...: for i in alist:
...: print(i)
[1]
[3, 4]
i
is one of the sublists, not an index! Trying to use it as an index produces an error:
In [96]: alist = [[1],[3,4]]
...: for i in alist:
...: print(alist[i])
Traceback (most recent call last):
Input In [96] in <cell line: 2>
print(alist[i])
TypeError: list indices must be integers or slices, not list
Use for i in range(len(arr)):
if you want to generate indices. Or for i,v in enumerate(arr):
to get indices and values.
But the error you got suggests that final_array
was an array of floats, not integers that the code sample produces.
The ambiguity error
that I got was the result of using
In [98]: Out[94]<0
Out[98]:
array([[False, False, True, False],
[False, False, True, False],
[False, True, False, False],
[False, False, True, False]])
the if
statement. if
requires a simple True/False. It doesn't do any sort of iteration
.
Even proper indexing of a row of final_array
would give this ambiguity error
In [100]: final_array[0]<0
Out[100]: array([False, False, True, False])
The if
only works if you are testing scalar elements of the array. For example if the array was 1d:
In [101]: x = np.arange(-3,4)
In [102]: for i in range(len(x)):
...: if x[i]<0:
...: x[i] = 0
...:
In [103]: x
Out[103]: array([0, 0, 0, 0, 1, 2, 3])
But usually in numpy
we don't need to iterate (or rather prefer not to). Instead we can test all the values at once. Sticking with the 1d array for simplicity:
In [104]: x = np.arange(-3,4)
In [105]: mask = x<0
In [106]: mask
Out[106]: array([ True, True, True, False, False, False, False])
In [107]: x[mask]
Out[107]: array([-3, -2, -1])
In [108]: x[mask] = 0
In [109]: x
Out[109]: array([0, 0, 0, 0, 1, 2, 3])