1

I have a sparse matrix (numpy.array) and I would like to have the index of the nonzero elements in it.

In Matlab I would write:

[i, j] = find(CM)

and in Python what should I do? I have tried numpy.nonzero (but I don't know how to take the indices from that) and flatnonzero (but it's not convenient for me, I need both the row and column index).

Thanks in advance!

2
  • 2
    Have a look at this question about numpy.nonzero (and the comment to the answer). Or check the numpy.nonzero documentation - that also explains how to interpret the output. Commented Sep 26, 2013 at 15:46
  • I had seen that (and all the other related questions) before posting this and I still had some doubts (this is why i posted in here, to have different points of view in order to understand better) and of course I have read the numpy documentation first of all but it doesn't have many examples to sometimes it is hard for me to understand it since i'm a beginner. Commented Oct 1, 2013 at 8:12

2 Answers 2

3

Assuming that by "sparse matrix" you don't actually mean a scipy.sparse matrix, but merely a numpy.ndarray with relatively few nonzero entries, then I think nonzero is exactly what you're looking for. Starting from an array:

>>> a = (np.random.random((5,5)) < 0.10)*1
>>> a
array([[0, 0, 0, 0, 0],
       [0, 0, 0, 0, 1],
       [0, 0, 1, 0, 0],
       [1, 0, 0, 0, 0],
       [0, 0, 0, 0, 0]])

nonzero returns the indices (here x and y) where the nonzero entries live:

>>> a.nonzero()
(array([1, 2, 3]), array([4, 2, 0]))

We can assign these to i and j:

>>> i, j = a.nonzero()

We can also use them to index back into a, which should give us only 1s:

>>> a[i,j]
array([1, 1, 1])

We can even modify a using these indices:

>>> a[i,j] = 2
>>> a
array([[0, 0, 0, 0, 0],
       [0, 0, 0, 0, 2],
       [0, 0, 2, 0, 0],
       [2, 0, 0, 0, 0],
       [0, 0, 0, 0, 0]])

If you want a combined array from the indices, you can do that too:

>>> np.array(a.nonzero()).T
array([[1, 4],
       [2, 2],
       [3, 0]])

(there are lots of ways to do this reshaping; I chose one almost at random.)

Sign up to request clarification or add additional context in comments.

1 Comment

I think zip(i,j) is the more conventional way to get a list of coordinate pairs, unless you need an array (though if you need an array, you probably want it in the original unzipped form anyway since slicing and plotting are not done by coordinate pairs).
0

This goes slightly beyond what you as and I only mention it since I once faced a similar problem. If you want the indices to access some other array there is some very simple sytax:

import numpy as np

array = np.random.randint(0, 2, size=(3, 3))

data = np.random.random(size=(3, 3))

Now array looks something like

>>> print array
array([[0, 1, 0],
       [1, 0, 1],
       [1, 1, 0]])

while data could be

>>> print data
array([[ 0.92824816,  0.43605604,  0.16627849],
       [ 0.00301434,  0.94342538,  0.95297402],
       [ 0.32665135,  0.03504204,  0.86902492]])

Then if we want the elements of data which are zero:

>>> print data[array==0]
array([ 0.92824816,  0.16627849,  0.94342538,  0.86902492])

Which is nice and simple.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.