4

I am unable to iterate over the outer axis of a numpy array.

import numpy as np

a = np.arange(2*3).reshape(2,3)
it = np.nditer(a)
for i in it:
    print i

and this gives, as one would expect:

0
1
2
3
4
5

I would, however, like the output to come in threes, such that I have iterated over the outer axes:

(0, 1, 2)
(3, 4, 5)

I know of many ways in which I can achieve this, but after pouring over the nditer documentation, I can't seem to find a solution using nditer. I am using this as an opportunity to learn nditer. So I would prefer not using other solutions, unless it is genuinely more efficient or pythonic.

2
  • 1
    Try commenting the it = np.nditer(a) line Commented Mar 25, 2017 at 15:57
  • I'm using this as an example to learn nditer. I know that I can iterate through the outer dimension using "for i in a:" Commented Mar 25, 2017 at 16:44

2 Answers 2

3

It's easier to control the iteration with a plain for:

In [17]: a
Out[17]: 
array([[0, 1, 2],
       [3, 4, 5]])
In [18]: for row in a:
    ...:     print(row)
    ...:     
[0 1 2]
[3 4 5]

Doing this with nditer is just plain awkward. Unless you need broadcasting use cython as described at the end of the page, nditer does not offer any speed advantages. Even with cython, I've gotten better speeds with memoryviews than with nditer.

Look at np.ndindex. It creates a dummy array with reduced dimensions, and does a nditer on that:

In [20]: for i in np.ndindex(a.shape[0]):
    ...:     print(a[i,:])
    ...:     
[[0 1 2]]
[[3 4 5]]

Got it:

In [31]: for x in np.nditer(a.T.copy(), flags=['external_loop'], order='F'):
    ...:     print(x)

[0 1 2]
[3 4 5]

Like I said - awkward

I recently explored the difference between direct iteration and nditer over a 1d structured array: https://stackoverflow.com/a/43005985/901925

Sign up to request clarification or add additional context in comments.

1 Comment

Perfect! Exactly what I wanted to know. I was mistakenly under the impression that nditer would give me a speed advantage. And yes, this is awkward and unnecessary. Duly noted! thank you @hpaulj
0

You can iterate it over just like you iterate over a 1D array to get the output like you want.

 for k,v in enumerate(a):
      print(v)

4 Comments

thanks! As I said, I know of many ways of doing this, including this. In your answer, you can even get rid of enumerate, to get the same result. I'm looking for answers that uses nditer.
as it is mentioned in numpy nditer docs that "nditer supersedes flatiter. " docs.scipy.org/doc/numpy/reference/generated/…
can you please describe what are you trying to do ?
I want to achieve what your solution would give. But I am trying to learn nditer, so I am looking for a solution that would use nditer. I don't understand what your point is by mentioning: "nditer supersedes flatiter.". I know this, and I'm trying to use this fact to make a generator that only spits out the outer axis, and not every element in the array.

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.