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.
NumPy package contains an iterator object numpy. It is an efficient multidimensional iterator object using which it is possible to iterate over an array. Each element of an array is visited using Python's standard Iterator interface.
nditer() is the most popular function in Numpy. The main purpose of the nditer() function is to iterate an array of objects. We can iterate multidimensional arrays using this function. We can also get a Transpose of an array which is simply known as converting a row into columns and columns into rows using “flags“.
What you propose is quite fast, but the legibility can be improved with the clearer forms:
for i in range(c.shape[-1]): print c[:,:,i]
or, better (faster, more general and more explicit):
for i in range(c.shape[-1]): print c[...,i]
However, the first approach above appears to be about twice as slow as the swapaxes()
approach:
python -m timeit -s 'import numpy; c = numpy.arange(24).reshape(2,3,4)' \ 'for r in c.swapaxes(2,0).swapaxes(1,2): u = r' 100000 loops, best of 3: 3.69 usec per loop python -m timeit -s 'import numpy; c = numpy.arange(24).reshape(2,3,4)' \ 'for i in range(c.shape[-1]): u = c[:,:,i]' 100000 loops, best of 3: 6.08 usec per loop python -m timeit -s 'import numpy; c = numpy.arange(24).reshape(2,3,4)' \ 'for r in numpy.rollaxis(c, 2): u = r' 100000 loops, best of 3: 6.46 usec per loop
I would guess that this is because swapaxes()
does not copy any data, and because the handling of c[:,:,i]
might be done through general code (that handles the case where :
is replaced by a more complicated slice).
Note however that the more explicit second solution c[...,i]
is both quite legible and quite fast:
python -m timeit -s 'import numpy; c = numpy.arange(24).reshape(2,3,4)' \ 'for i in range(c.shape[-1]): u = c[...,i]' 100000 loops, best of 3: 4.74 usec per loop
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With