5

Given a numpy array

A = np.array([[[29, 64, 83],
               [17, 92, 38],
               [67, 34, 20]],
              [[73, 28, 45],
               [19, 84, 61],
               [22, 63, 49]],
              [[48, 30, 13],
               [11, 52, 86],
               [62, 25, 12]]])

I want the index of a certain value, say 63

There is no possibility that the value will be duplicated or missing

I did

idx = np.where(A == 63)

print(idx)

I got

(array([1], dtype=int32), array([2], dtype=int32), array([1], dtype=int32))

What I want is

[1, 2, 1]

as a list or other iterable without all that array, dtype=int32 etc.

How do I do this?

3 Answers 3

3

If you want to get a numpy array back, just use the concatenate function:

In [30]: np.concatenate(idx)
Out[30]: array([1, 2, 1])

If you really have your heart set on a Python list, then just:

In [31]: np.concatenate(idx).tolist()
Out[31]: [1, 2, 1]
Sign up to request clarification or add additional context in comments.

Comments

3

What about this approach using list-comprehensions?

   idx = [x[0] for x in np.where(A==63)]

4 Comments

That seems to work. Thanks. I will have to study it to understand what it is doing.
Check out list comprehension if yo want to know how it works.
What I don't understand is what the 0 in x[0] is doing
It's pulling of the value from the array[...]
1

Numpy arrays support returning elements where a condition is true. You can use np.where(..) or use:

>>> A==63
array([[[False, False, False],
        [False, False, False],
        [False, False, False]],

       [[False, False, False],
        [False, False, False],
        [False,  True, False]],

       [[False, False, False],
        [False, False, False],
        [False, False, False]]], dtype=bool)

You can then flatten that index array to only the True values using an array's .nonzero() method:

>>> (A==63).nonzero()
(array([1]), array([2]), array([1]))

Note that is a Python tuple of numpy arrays with the first being the X index, the second being the Y and then Z in A[X,Y,Z] form.

For one element only, you could then flatten that using .r_:

>>> np.r_[(A==63).nonzero()]
array([1, 2, 1])

And you can produce a Python list if you wish:

>>> np.r_[(A==63).nonzero()].tolist()
[1, 2, 1]

A more interesting use case is when you have more than one index in the matrix that is True. Consider all values >63:

>>> A>63
array([[[False,  True,  True],
        [False,  True, False],
        [ True, False, False]],

       [[ True, False, False],
        [False,  True, False],
        [False, False, False]],

       [[False, False, False],
        [False, False,  True],
        [False, False, False]]], dtype=bool)

You can also use .nonzero() method or the nonzero function:

>>> np.nonzero(A>63)
(array([0, 0, 0, 0, 1, 1, 2]), array([0, 0, 1, 2, 0, 1, 1]), array([1, 2, 1, 0, 0, 1, 2]))
     ^^^ X's                      ^^^ Y's                              ^^^ Z's

Notice now that this is a tuple of 3 arrays (in this case) of all X's, all Y's, all Z's in that order.

You can use np.transpose to produce an array of those element indexes of the form [[X, Y, Z],...] like so:

>>> np.transpose((A>63).nonzero())
array([[0, 0, 1],
       [0, 0, 2],
       [0, 1, 1],
       [0, 2, 0],
       [1, 0, 0],
       [1, 1, 1],
       [2, 1, 2]])

Or (suitable for printing for human eyes for example) you can use zip:

>>> zip(*(A>63).nonzero())
[(0, 0, 1), (0, 0, 2), (0, 1, 1), (0, 2, 0), (1, 0, 0), (1, 1, 1), (2, 1, 2)]

Or, to print:

>>> print '\n'.join([str(e) for e in zip(*(A>63).nonzero())])
(0, 0, 1)
(0, 0, 2)
(0, 1, 1)
(0, 2, 0)
(1, 0, 0)
(1, 1, 1)
(2, 1, 2)

Which, of course, would work for a single element just as well:

>>> zip(*(A==63).nonzero())[0]
(1, 2, 1)

Or numpy way:

>>> np.transpose((A==63).nonzero())[0]
array([1, 2, 1])

All the methods here works with np.where(A==63) in place of (A==63).nonzero() as an example.

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.