Access all elements at given x, y position in 3-dimensional numpy array
<pre><code>mat_a = np.random.random((5, 5))
mat_b = np.random.random((5, 5))
mat_c = np.random.random((5, 5))
bigmat = np.stack((mat_a, mat_b, mat_c)) # this is a 3, 5, 5 array

for (x, y, z), value in np.ndenumerate(bigmat):
    print (x, y, z)
</code></pre>

<p>In the example above, how can I loop so that I iterate only across the 5 x 5 array and at each position I get 3 values i.e. loop should run 25 times and each time, I get an array with 3 values (one from each of mat_a, mat_b and mat_c)</p>

<ul>
<li>EDIT: Please note that I need to be able to access elements by position later i.e. if <code>bigmat</code> is reshaped, there should be a way to access element based on specific y, z</li>
</ul>

<p>There is a function that generates all indices for a given shape, <code>ndindex</code>.  </p>

<pre><code>for y,z in np.ndindex(bigmat.shape[1:]):
    print(y,z,bigmat[:,y,z])

0 0 [ 0 25 50]
0 1 [ 1 26 51]
0 2 [ 2 27 52]
0 3 [ 3 28 53]
0 4 [ 4 29 54]
1 0 [ 5 30 55]
1 1 [ 6 31 56]
...
</code></pre>

<p>For a simple case like this it isn't much easier than the double <code>for range</code> loop.  Nor will it be faster; but you asked for an iteration.</p>

<p>Another iterator is <code>itertools.product(range(5),range(5))</code></p>

<p>Timewise, product is pretty good:</p>

<pre><code>In [181]: timeit [bigmat[:,y,z] for y,z in itertools.product(range(5),range(5
     ...: ))]
10000 loops, best of 3: 26.5 Âµs per loop

In [191]: timeit [bigmat[:,y,z] for (y,z),v in np.ndenumerate(bigmat[0,...])]
     ...: 
10000 loops, best of 3: 61.9 Âµs per loop
</code></pre>

<p>transposing and reshaping is the fastest way to get a list (or array) of the triplets - but it does not give the indices as well:</p>

<pre><code>In [198]: timeit list(bigmat.transpose(1,2,0).reshape(-1,3))
100000 loops, best of 3: 15.1 Âµs per loop
</code></pre>

<p>But the same operation gets the indices from <code>np.mgrid</code> (or <code>np.meshgrid</code>):</p>

<pre><code>np.mgrid[0:5,0:5].transpose(1,2,0).reshape(-1,2)
</code></pre>

<p>(though this is surprisingly slow)</p>

python numpy