NumPy 迭代器对象 numpy.nditer 提供了一种灵活访问一个或者多个数组元素的方式。
迭代器最基本的任务的可以完成对数组元素的访问。
接下来我们使用 arange() 函数创建一个 2X3 数组,并使用 nditer 对它进行迭代。
import numpy as np
a = np.arange(6).reshape(2,3)
print ('迭代输出元素:')
for x in np.nditer(a):
print (x,end=",")
![image]()
在 a.T.copy(order='C') 中,order 参数用于控制数组副本的内存布局方式。以下是各选项的区别:
'C'(C 风格顺序):采用行优先(row-major)存储方式。在多维数组中,先存储第一行的所有元素,接着是第二行的元素,依此类推。对于二维数组,元素在内存中按行依次排列,即 arr[0, 0]、arr[0, 1]、arr[0, 2] ... arr[1, 0]、arr[1, 1] ... 适用于与 C 和 Python 语言交互或进行按行访问操作。
'F'(Fortran 风格顺序):采用列优先(column-major)存储方式。在多维数组中,先存储第一列的所有元素,接着是第二列的元素,依此类推。适用于与 Fortran 语言交互或进行按列访问操作。
'A':如果数组是 Fortran 连续的(即列优先存储),则使用 'F';否则使用 'C'。这通常用于保持原数组的内存连续性。
'K':尽可能匹配原数组的内存布局。这意味着复制后的数组会保持与原数组相同的内存布局顺序。
转置数组:a.T 会将数组的行和列进行交换。
import numpy as np
a = np.arange(6).reshape(2,3)
print(a)
print("$"*30)
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')
for x in np.nditer(a.T.copy(order="A")):
print (x, end=", " )
print('\n')
for x in np.nditer(a.T.copy(order="F")):
print (x, end=", " )
print('\n')
for x in np.nditer(a.T.copy(order="K")):
print (x, end=", " )
![image]()
import numpy as np
a = np.arange(6).reshape(2,3)
print(a)
print("$"*30)
for x in np.nditer(a.T.copy(order="C")):
print (x, end=", " )
print('\n')
for x in np.nditer(a,order="C"):
print (x, end=", " )
- `a.T.copy(order='C')` 创建了一个转置数组的副本,按照 C 风格存储,元素顺序为 `0, 3, 1, 4, 2, 5`
- `a` 按照 C 风格遍历时,元素顺序为 `0, 1, 2, 3, 4, 5`
两个遍历方式虽然都使用了 C-order,但因为原始数组不同,输出结果也不同。
import numpy as np
a = np.arange(6).reshape(2,3)
print(a)
print("$"*30)
for x in np.nditer(a.T,order="C"):
print (x, end=", " )
print('\n')
for x in np.nditer(a,order="C"):
print (x, end=", " )
print('\n')
for x in np.nditer(a,order="F"):
print (x, end=", " )
![image]()
当对转置数组 `a.T` 使用 `order='C'` 时,由于 `a.T` 本身是原数组的视图,其内存布局与原数组不同,但指定 `order='C'` 后,`np.nditer` 会按照 C 风格的顺序来访问元素,这可能导致与直接对原数组遍历不同的结果。
需要注意的是,`a.T` 和 `a` 的内存布局不同,因此即使都使用 `order='C'`,遍历结果可能不同。
修改数组中元素的值
nditer 对象有另一个可选参数 op_flags。 默认情况下,nditer 将视待迭代遍历的数组为只读对象(read-only),为了在遍历数组的同时,实现对数组元素值的修改,必须指定 readwrite 或者 writeonly 的模式。
import numpy as np
a = np.arange(0,60,5)
a = a.reshape(3,4)
print ('原始数组是:')
print (a)
for x in np.nditer(a, op_flags=['readwrite']):
x[...]=2*x
print ('修改后的数组是:')
print (a)
![image]()
广播迭代
如果两个数组是可广播的,nditer 组合对象能够同时迭代它们。 假设数组 a 的维度为 3X4,数组 b 的维度为 1X4 ,则使用以下迭代器(数组 b 被广播到 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=", " )