Adarsh Namdev
Adarsh Namdev

Reputation: 127

Why am I getting so many indices when a 2D ndarray is passed into nonzero function?

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

Answers (2)

Imperishable Night
Imperishable Night

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

Mark
Mark

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

Related Questions