07NumPy Learning - Iterating Arrays

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

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

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

import numpy as np
 
a = np.arange(6).reshape(2,3)
print ('原始数组是:')
print (a)
print ('\n')
print ('迭代输出元素:')
for x in np.nditer(a):
    print (x, end=", " )

The output result is:
The original array is:
[ [0 1 2]
  [3 4 5] ]

Iterative output elements:
0, 1, 2, 3, 4, 5,

The above example does not use the standard C or Fortran order. The order of selection is consistent with the memory layout of the array . This is to improve the efficiency of access. The default is row-major order (or C-order).

This reflects that by default only each element needs to be accessed, regardless of its specific order. We can see this by iterating over the transpose of the above array, and contrast it with the copy way of accessing the transpose of the array in C order, as in the following example:

import numpy as np
 
a = np.arange(6).reshape(2,3)

print('原数组是:')
print(a)
print('\n')

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=", " )

The output result is:
the original array is:
[ [0 1 2]
  [3 4 5] ]

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

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

As can be seen from the above example, the traversal order of a and aT is the same, that is, their storage order in memory is also the same, but the traversal result of aTcopy(order = 'C') is different, that is because it It is different from the first two storage methods, and the default is row-by-row access.

control traversal order

  • for x in np.nditer(a, order='F'): Fortran order, that is, column sequence priority;
  • for x in np.nditer(aT, order='C'): C order, which is row order priority;
import numpy as np
 
a = np.arange(0,60,5).reshape(3,4)

print ('原始数组是:') 
print (a) 
print ('\n')

print ('原始数组的转置是:') 
b = a.T 
print (b) 
print ('\n')

print ('以 C 风格顺序排序:') 
c = b.copy(order='C')  
print (c)
for x in np.nditer(c):  
    print (x, end=", " )
print  ('\n') 

print  ('以 F 风格顺序排序:')
c = b.copy(order='F')  
print (c)
for x in np.nditer(c):  
    print (x, end=", " )

The output is:
the original array is:
[ [ 0 5 10 15]
  [20 25 30 35]
  [40 45 50 55] ]

The transpose of the original array is:
[ [ 0 20 40]
  [ 5 25 45]
  [10 30 50 ]
  [15 35 55] ]

Sort in C-style order:
[ [ 0 20 40]
  [ 5 25 45]
  [10 30 50]
  [15 35 55] ]
0, 20, 40, 5, 25, 45, 10, 30 , 50, 15, 35, 55,

in F-style order:
[ [ 0 20 40]
  [ 5 25 45]
  [10 30 50]
  [15 35 55] ]
0, 5, 10, 15, 20, 25, 30 , 35, 40, 45, 50, 55,

It is possible to force nditer objects to use a certain order by explicitly setting:

import numpy as np 
 
a = np.arange(0,60,5) 
a = a.reshape(3,4)  
print ('原始数组是:')
print (a)
print ('\n')
print ('以 C 风格顺序排序:')
for x in np.nditer(a, order =  'C'):  
    print (x, end=", " )
print ('\n')
print ('以 F 风格顺序排序:')
for x in np.nditer(a, order =  'F'):  
    print (x, end=", " )

The output is:
The original array is:
[ [ 0 5 10 15]
  [20 25 30 35]
  [40 45 50 55] ]

in C-style order:
0, 5, 10, 15, 20, 25, 30, 35, 40, 45, 50, 55,

in F-style order:
0, 20, 40, 5, 25, 45, 10, 30, 50, 15, 35, 55,

Modifying the value of an element in an array
nditer object has another optional parameter op_flags. By default, nditer will treat the array to be iteratively traversed as a read-only object (read-only). In order to traverse the array while modifying the elements of the array, the read-write or write-only mode must be specified.

import numpy as np
 
a = np.arange(0,60,5) 
a = a.reshape(3,4)  
print ('原始数组是:')
print (a)
print ('\n')
for x in np.nditer(a, op_flags=['readwrite']): 
    x[...]=2*x 
print ('修改后的数组是:')
print (a)

The output is:
the original array is:
[ [ 0 5 10 15]
  [20 25 30 35]
  [40 45 50 55] ]

The modified array is:
[ [ 0 10 20 30]
  [ 40 50 60 70]
  [ 80 90 100 110] ]


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

parameter describe
c_index Indexes that can track C-order
f_index Indexes that can track Fortran order
multi-index One index type can be tracked per iteration
external_loop The value given is a one-dimensional array with multiple values, not a zero-dimensional array

In the example below, iterators are traversed corresponding to each column and combined into a one-dimensional array.

import numpy as np 

a = np.arange(0,60,5) 
a = a.reshape(3,4)  
print ('原始数组是:')
print (a)
print ('\n')
print ('修改后的数组是:')
for x in np.nditer(a, flags =  ['external_loop'], order =  'F'):  
   print (x, end=", " )

The output is:
the original array is:
[ [ 0 5 10 15]
  [20 25 30 35]
  [40 45 50 55] ]

The modified array is:
[ 0 20 40], [ 5 25 45], [10 30 50 ], [15 35 55],

broadcast iteration

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

import numpy as np 
 
a = np.arange(0,60,5) 
a = a.reshape(3,4)  
print  ('第一个数组为:')
print (a)
print  ('\n')
print ('第二个数组为:')
b = np.array([1,  2,  3,  4], dtype =  int)  
print (b)
print ('\n')
print ('修改后的数组为:')
for x,y in np.nditer([a,b]):  
    print ("%d:%d"  %  (x,y), end=", " )

The output result is:
The first array is:
[ [ 0 5 10 15]
  [20 25 30 35]
  [40 45 50 55] ]

The second array is:
[1 2 3 4]

The modified array is:
0: 1, 5:2, 10:3, 15:4, 20:1, 25:2, 30:3, 35:4, 40:1,

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=326139696&siteId=291194637