Tanmay
Tanmay

Reputation: 1321

Python numpy nditer skipping alternate elements

I am trying to iterate over two 2D arrays. But, somehow iterator skips every alternate element in row. 'bimg' and 'dist'size is 20x12. But, for every row, it iterates over 0, 2, 4 ... columns instead of 0,1,2,3,4, ...

Code snippet:

it = np.nditer([bimg, dist], 
               op_flags=[['readonly'],['readonly']], 
               flags = ['multi_index', 'multi_index'])
rows, cols = bimg.shape
print "bimg dimensions: ", bimg.shape
print "dist dimensions: ", dist.shape
for cur_b, cur_d in it:
    print "MULTI_IDX = ", it.multi_index

Output:

bimg dimensions:  (20L, 12L)
dist dimensions:  (20L, 12L)
MULTI_IDX =  (0, 0)
MULTI_IDX =  (0, 2)
MULTI_IDX =  (0, 4)
MULTI_IDX =  (0, 6)
MULTI_IDX =  (0, 8)
MULTI_IDX =  (0, 10)
MULTI_IDX =  (1, 0)
MULTI_IDX =  (1, 2)

To understand this issue, if I create array on python prompt and try to iterate over it works correctly:

Correctly working code:

x = np.array(np.arange(240))
x = x.reshape(20,12)
y = np.array(np.arange(240))
y = y + 100
y = y.reshape(20,12)
it = np.nditer([x,y], 
               op_flags = [['readonly'],['readonly']], 
               flags= ['multi_index', 'multi_index'])
for a, b in it:
    print it.multi_index               

Output:

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

Upvotes: 1

Views: 737

Answers (1)

hpaulj
hpaulj

Reputation: 231425

I don't see the difference. When I define:

bimg = x
dist = y

I get the same iteration with both clips.

flags only needs 'multi_index' once. It applies to the whole iteration, op_flags to each array:

flags= ['multi_index']

While the documentation describes nditer as efficient multi-dimensional iterator object, it doesn't seem to help much with speed in Python code. In C or Cython is streamlines the whole process of iterating over multiple array.

Here's another way of generating the multi_index. Actually it's not so different. Internally ndindex constructs a dummy array of the desired shape, and returns an iterable. Look at its code.

for i, j in np.ndindex(bimg.shape):
     print i,j

According the tutorial Iterating over Array page, the correct way to use multi_index is with the c style iterator:

while not it.finished:
    print it.multi_index
    it.iternext()

I'm not sure why. What are the dtypes of bimg and dist?

Upvotes: 2

Related Questions