在您的第一个迭代示例中:
In [1]: arr = np.arange(12).reshape(3,4)
In [2]: for x in np.nditer(arr, op_flags=['readwrite']):
...: print(x, type(x))
...: x[...] = 2 * x
...:
0
1
2
3
4
....
11
In [3]: x
Out[3]: array(22)
In [4]: arr
Out[4]:
array([[ 0, 2, 4, 6],
[ 8, 10, 12, 14],
[16, 18, 20, 22]])
打开multi_index:
In [9]: it = np.nditer(arr, flags=['multi_index'],op_flags=['readwrite'])
In [10]: while not it.finished:
...: print(it[0], it.multi_index)
...: it.iternext()
...:
0 (0, 0)
2 (0, 1)
4 (0, 2)
...
20 (2, 2)
22 (2, 3)
通过arr的元素进行相同的迭代,但是还会生成2d索引元组.它是nditer对象,具有各种方法和属性.在这种情况下,它具有multi_index属性.和当前迭代变量是在它[0].
我可以使用[…]就位或通过在arr中建立索引来修改元素:
In [11]: it = np.nditer(arr, flags=['multi_index'],op_flags=['readwrite'])
In [13]: while not it.finished:
...: it[0][...] *= 2
...: arr[it.multi_index] += 100
...: it.iternext()
...:
In [14]: arr # values are doubled and add by 100
Out[14]:
array([[100, 104, 108, 112],
[116, 120, 124, 128],
[132, 136, 140, 144]])
没有multi_index,我仍然可以创建一个nditer对象,并使用未完成的语法进行迭代.而不是访问x […],我不得不使用它[0] […].
np.ndindex是一种生成multi_index的更方便的方法.看一下它的代码.它是使用np.nditer的少数numpy函数之一.
In [26]: for idx in np.ndindex(arr.shape):
...: print(idx)
...: arr[idx] -= 100
...:
(0, 0)
(0, 1)
...
(2, 3)
In [27]: arr
Out[27]:
array([[ 0, 4, 8, 12],
[16, 20, 24, 28],
[32, 36, 40, 44]])
但
尽管与nditer一起玩很有趣,但它并不实际,至少在纯Python代码中不是这样.作为在cython或纯c代码中使用它的垫脚石,它最有用.请参阅迭代页面的最终示例.