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.