Reputation: 127
I trying to find out the non-zero elements in a 2D ndarray. When I passed my array into np.nonzero() function, I am getting the same index multiple times.
import numpy as np
ar1 = np.array([[4,7,3,0,0,1],[4,1,1,0,1,6]])
items_not_zero = np.nonzero(ar1)
print(items_not_zero)
# (array([0, 0, 0, 0, 1, 1, 1, 1, 1]), array([0, 1, 2, 5, 0, 1, 2, 4, 5]))
I was expecting to have a tuple with the indices of the non-zero elements just once..
Upvotes: 0
Views: 53
Reputation: 1533
First, you should look at the documentation page for numpy.nonzero
.
Basically, what nonzero
returns is a tuple of arrays immediately suitable for indexing:
ar1[(np.array([0, 0, 0, 0, 1, 1, 1, 1, 1]), np.array([0, 1, 2, 5, 0, 1, 2, 4, 5]))]
# array([4, 7, 3, 1, 4, 1, 1, 1, 6])
This means that the number of arrays returned is equal to the number of dimensions of your array (e.g. ar1
is a 2-D array), and each group of numbers on the same position is an index into the original array. For example, the third element of those arrays are 0 and 2 respectively, which means arr[0][2]
is nonzero.
An easy way to make the result more "human-readable", as the documentation page mentions, is to transpose it:
np.transpose(np.nonzero(ar1))
'''
array([[0, 0],
[0, 1],
[0, 2],
[0, 5],
[1, 0],
[1, 1],
[1, 2],
[1, 4],
[1, 5]])
'''
Upvotes: 1
Reputation: 92461
np.nonzero
returns an array for each dimension of the array passed in. In your example
(array([0, 0, 0, 0, 1, 1, 1, 1, 1]), array([0, 1, 2, 5, 0, 1, 2, 4, 5]))
corresponds to the indexes:
[(0, 0), (0, 1), (0, 2), (0, 5), (1, 0), (1, 1), (1, 2), (1, 4), (1, 5)]
…the first array corresponds to the [0]
coordinate and the next corresponds to the [1]
dimension of each tuple.
You can zip
these together or, as the docs mention you can get a list of tuples with:
print(np.transpose(np.nonzero(ar1)))
Upvotes: 2