views:

470

answers:

3

Is there function to get an iterator over an arbitrary dimension of a numpy array?

Iterating over the first dimension is easy...

In [63]: c = numpy.arange(24).reshape(2,3,4)

In [64]: for r in c :
   ....:     print r
   ....: 
[[ 0  1  2  3]
 [ 4  5  6  7]
 [ 8  9 10 11]]
[[12 13 14 15]
 [16 17 18 19]
 [20 21 22 23]]

But iterating over other dimensions is harder. For example, the last dimension:

In [73]: for r in c.swapaxes(2,0).swapaxes(1,2) :
   ....:     print r
   ....: 
[[ 0  4  8]
 [12 16 20]]
[[ 1  5  9]
 [13 17 21]]
[[ 2  6 10]
 [14 18 22]]
[[ 3  7 11]
 [15 19 23]]

I'm making a generator to do this myself, but I'm surprised there isn't a function named something like numpy.ndarray.iterdim(axis=0) to do this automatically.

A: 

There is special Ellipsis object in python which can be passed to __getitem__ or written as ... in slice operations:

>>> c[..., ..., 0]
array([[ 0,  4,  8],
       [12, 16, 20]])
Denis Otkidach
@Denis: The ellipsis is less appropriate here than ":": the ellipsis is intended to represent any number of ":". Your `c[...,...,0]` would thus be better written as `c[...,0]`.
EOL
+1  A: 

It looks to me like what you propose is a good way of doing what you want!

Alternatively, you can use the clearer form:

for i in range(c.shape[2]):
    print c[:,:,i]
EOL
A: 

I guess there is no function. When I wrote my function, I ended up taking the iteration EOL also suggested. For future readers, here it is:

def iterdim(a, axis=0) :
  a = numpy.asarray(a);
  leading_indices = (slice(None),)*axis
  for i in xrange(a.shape[axis]) :
    yield a[leading_indices+(i,)]
AFoglia