NumPy Iterating Arrays

The NumPy iterator object numpy.nditer provides a flexible way to access one or more array elements.

The most basic task of the iterator is to access array elements.

Next, we use the arange() function to create a 2X3 array, and use nditer to iterate over it.

Example

import numpy as np a = np.arange(6).reshape(2,3) print ('The original array is:') print (a) print ('\n') print ('Iterating over the elements:') for x in np.nditer(a): print (x, end=", " ) print ('\n')

The output result is:

原始数组是:
[[0 1 2]
 [3 4 5]]


迭代输出元素:
0, 1, 2, 3, 4, 5, 

The above examples do not use standard C or Fortran order; the chosen order is consistent with the array's memory layout, in order to improve access efficiency. The default is row-major order (or C-order).

This reflects that by default, each element is simply accessed without considering its specific order. We can see this by iterating over the transpose of the above array, and comparing it with the copy method that accesses the array transpose in C order, as in the following example:

Example

import numpy as np a = np.arange(6).reshape(2,3) for x in np.nditer(a.T): print (x, end=", " ) print ('\n') for x in np.nditer(a.T.copy(order='C')): print (x, end=", " ) print ('\n')

The output result is:

0, 1, 2, 3, 4, 5, 

0, 3, 1, 4, 2, 5, 

As can be seen from the above examples, the traversal order of a and a.T is the same, meaning they also have the same storage order in memory, buta.T.copy(order = 'C')has a different traversal result, because its storage method is different from the previous two, and by default it is accessed row-wise.

Controlling Traversal Order

  • for x in np.nditer(a, order='F'):Fortran order, i.e., column-major order;
  • for x in np.nditer(a.T, order='C'):C order, i.e., row-major order;

Example

import numpy as np a = np.arange(0,60,5) a = a.reshape(3,4) print ('The original array is:') print (a) print ('\n') print ('The transpose of the original array is:') b = a.T print (b) print ('\n') print ('In C-style order:') c = b.copy(order='C') print (c) for x in np.nditer(c): print (x, end=", " ) print ('\n') print ('In F-style order:') c = b.copy(order='F') print (c) for x in np.nditer(c): print (x, end=", " )

The output result is:

原始数组是:
[[ 0  5 10 15]
 [20 25 30 35]
 [40 45 50 55]]


原始数组的转置是:
[[ 0 20 40]
 [ 5 25 45]
 [10 30 50]
 [15 35 55]]


以 C 风格顺序排序:
[[ 0 20 40]
 [ 5 25 45]
 [10 30 50]
 [15 35 55]]
0, 20, 40, 5, 25, 45, 10, 30, 50, 15, 35, 55, 

以 F 风格顺序排序:
[[ 0 20 40]
 [ 5 25 45]
 [10 30 50]
 [15 35 55]]
0, 5, 10, 15, 20, 25, 30, 35, 40, 45, 50, 55,

You can force the nditer object to use a certain order by explicitly setting it:

Example

import numpy as np a = np.arange(0,60,5) a = a.reshape(3,4) print ('The original array is:') print (a) print ('\n') print ('In C-style order:') for x in np.nditer(a, order = 'C'): print (x, end=", " ) print ('\n') print ('In F-style order:') for x in np.nditer(a, order = 'F'): print (x, end=", " )

The output result is:

原始数组是:
[[ 0  5 10 15]
 [20 25 30 35]
 [40 45 50 55]]


以 C 风格顺序排序:
0, 5, 10, 15, 20, 25, 30, 35, 40, 45, 50, 55, 

以 F 风格顺序排序:
0, 20, 40, 5, 25, 45, 10, 30, 50, 15, 35, 55,

Modifying Array Element Values

The nditer object has another optional parameter, op_flags. By default, nditer treats the array to be iterated over as a read-only object. In order to modify the values of array elements while iterating over the array, you must specify readwrite or writeonly mode.

Example

import numpy as np a = np.arange(0,60,5) a = a.reshape(3,4) print ('The original array is:') print (a) print ('\n') for x in np.nditer(a, op_flags=['readwrite']): x[...]=2*x print ('The modified array is:') print (a)

The output result is:

原始数组是:
[[ 0  5 10 15]
 [20 25 30 35]
 [40 45 50 55]]


修改后的数组是:
[[  0  10  20  30]
 [ 40  50  60  70]
 [ 80  90 100 110]]

Using External Loop

The constructor of the nditer class has a flags parameter, which can accept the following values:

Parameter Description
c_index Can track the index in C order
f_index Can track the index in Fortran order
multi_index Can track one index type per iteration
external_loop The given value is a one-dimensional array with multiple values, rather than a zero-dimensional array

In the example below, the iterator traverses corresponding to each column and combines them into a one-dimensional array.

Example

import numpy as np a = np.arange(0,60,5) a = a.reshape(3,4) print ('The original array is:') print (a) print ('\n') print ('The modified array is:') for x in np.nditer(a, flags = ['external_loop'], order = 'F'): print (x, end=", " )

The output result is:

原始数组是:
[[ 0  5 10 15]
 [20 25 30 35]
 [40 45 50 55]]


修改后的数组是:
[ 0 20 40], [ 5 25 45], [10 30 50], [15 35 55],

Broadcasting Iteration

If two arrays are broadcastable, the nditer combination object can iterate over them simultaneously. Suppose array a has dimensions 3X4 and array b has dimensions 1X4, then the following iterator is used (array b is broadcast to the size of a).

Example

import numpy as np a = np.arange(0,60,5) a = a.reshape(3,4) print ('The first array is:') print (a) print ('\n') print ('The second array is:') b = np.array([1, 2, 3, 4], dtype = int) print (b) print ('\n') print ('The modified array is:') for x,y in np.nditer([a,b]): print ("%d:%d" % (x,y), end=", " )

The output result is:

第一个数组为:
[[ 0  5 10 15]
 [20 25 30 35]
 [40 45 50 55]]


第二个数组为:
[1 2 3 4]


修改后的数组为:
0:1, 5:2, 10:3, 15:4, 20:1, 25:2, 30:3, 35:4, 40:1, 45:2, 50:3, 55:4,
Other Extensions