NumPy 包含一个迭代器对象 numpy.nditer,它是一个高效的多维迭代器对象,用于迭代数组。每个元素都是使用标准 Python 迭代器接口一一提供的。
在下面的示例中,使用 arange() 函数创建数组,然后使用 nditer 用于迭代它。
import numpy as np
#创建一个数组
Arr = np.arange(10,25)
Arr = Arr.reshape(3,5)
#打印数组
print("原始数组为:")
print(Arr)
#使用 nditer 迭代数组
print("\n修改后的数组为:")
for i in np.nditer(Arr):
print(i, end=" ")
上述代码的输出将是:
原始数组为:
[[10 11 12 13 14]
[15 16 17 18 19]
[20 21 22 23 24]]
修改后的数组为:
10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
选择迭代顺序以匹配数组的内存布局使用标准 C 或 Fortran 排序的方法。这样做是为了提高访问效率,反映了这样一种想法:默认情况下,人们只想访问每个元素,而不关心特定的顺序。这可以通过迭代上述数组的转置来看出。
import numpy as np
#创建数组
Arr = np.arange(10,25)
Arr = Arr.reshape(3,5)
#打印数组
print("原始数组为:")
print(Arr)
#打印数组
print("\n转置后的数组为:")
print(Arr.T)
#迭代数组的转置
print("\n修改后的数组为:")
for i in np.nditer(Arr.T):
print(i, end=" ")
上述代码的输出将是:
原始数组为:
[[10 11 12 13 14]
[15 16 17 18 19]
[20 21 22 23 24]]
转置后的数组为:
[[10 15 20]
[11 16 21]
[12 17 22]
[13 18 23]
[14 19 24]]
修改后的数组为:
10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
迭代顺序
有例如,无论元素在内存中的布局如何,都必须以特定顺序访问数组的元素。 nditer 对象提供了一个 order 参数来控制迭代的这方面。默认值为 order='K' 以保持数组的现有顺序。对于 C 顺序,可以指定为 order='C',对于 Fortran 顺序,可以将其指定为 order='F'。
import numpy as np
#创建数组
Arr = np.arange(10,25)
Arr = Arr.reshape(3,5)
#打印数组
print("原始数组为:")
print(Arr)
#使用 order='K' 迭代数组
print("\n修改后的数组 (order='K'):")
for i in np.nditer(Arr, order='K'):
print(i, end=" ")
#使用 order='C' 迭代数组
print("\n\n修改后的数组 (order='C'):")
for i in np.nditer(Arr, order='C'):
print(i, end=" ")
#使用 order='F' 迭代数组
print("\n\n修改后的数组 (order='F'):")
for i in np.nditer(Arr, order='F'):
print(i, end=" ")
上述输出代码将是:
原始数组为:
[[10 11 12 13 14]
[15 16 17 18 19]
[20 21 22 23 24]]
修改后的数组 (order='K'):
10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
修改后的数组 (order='C'):
10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
修改后的数组 (order='F'):
10 15 20 11 16 21 12 17 22 13 18 23 14 19 24
修改数组值
nditer对象还有另一个可选参数,称为op_flags。默认情况下,nditer 将输入操作数视为只读对象。为了能够修改数组元素,必须使用 op_flags=['readwrite'] 或 op_flags=['writeonly'] 指定读写或只写模式i>.
import numpy as np
#创建数组
Arr = np.arange(10,25)
Arr = Arr.reshape(3,5)
#打印数组
print("原始数组为:")
print(Arr)
#修改数组的元素
for x in np.nditer(Arr, op_flags=['readwrite']):
x[...] = 2*x
#打印数组
print("\n修改后的数组为:")
print(Arr)
上述代码的输出将是:
原始数组为:
[[10 11 12 13 14]
[15 16 17 18 19]
[20 21 22 23 24]]
修改后的数组为:
[[20 22 24 26 28]
[30 32 34 36 38]
[40 42 44 46 48]]
外部循环
nditer对象还有另一个可选的参数名为flags,可以取以下值:
参数 | 说明 |
---|---|
c_index | 要跟踪的 C 顺序索引。 |
f_index | 要跟踪的 Fortran 顺序索引。 |
multi_index | 要跟踪的多索引或每个迭代维度一个索引的元组。 |
external_loop | 使给定的值成为具有多个值的一维数组,而不是零维数组。 |
range | 允许迭代器 限制为 iterindex 值的子范围。 |
在下面的例子中,迭代器遍历每一列对应的一维数组。
import numpy as np
#创建数组
Arr = np.arange(10,25)
Arr = Arr.reshape(3,5)
#打印数组
print("原始数组为:")
print(Arr)
#使用external_loop迭代数组
print("\n修改后的数组为:")
for i in np.nditer(Arr, flags = ['external_loop'], order = 'F'):
print(i, end=" ")
上述代码的输出将是:
原始数组为:
[[10 11 12 13 14]
[15 16 17 18 19]
[20 21 22 23 24]]
修改后的数组为:
[10 15 20] [11 16 21] [12 17 22] [13 18 23] [14 19 24]
广播数组迭代
如果两个数组可广播,组合的 nditer 对象能够同时迭代它们。
在下面的示例中,nditer 对象用于迭代同时处理数组arr1和arr2。 arr1 的维度为 (2x3),arr2 的维度为 (1x3)。
import numpy as np
#创建第一个数组
arr1 = np.arange(10,70,10)
arr1 = arr1.reshape(2,3)
#创建第二个数组
arr2 = np.array([1, 2, 3], dtype = int)
#打印数组
print("arr1 为:")
print(arr1)
print("\narr2 为:")
print(arr2)
#同时迭代两个数组
print("\n修改后的数组为:")
for x,y in np.nditer([arr1, arr2]):
print("%d:%d" % (x,y), end=" ")
上述代码的输出将是:
arr1 为:
[[10 20 30]
[40 50 60]]
arr2 为:
[1 2 3]
修改后的数组为:
10:1 20:2 30:3 40:1 50:2 60:3