在 NumPy 中跟踪多索引和修改值
Tracking Multi-Index and Modifying Values in NumPy
我有一个二维数组,我正在迭代它以努力使用索引值进行计算,然后将计算出的值分配给所述索引。
在 NumPy 文档中,an example 提供了使用迭代器修改值的方法:
for x in np.nditer(a, op_flags=['readwrite']):
x[...] = 2 * x
但是,当使用 the following method:
跟踪索引时,这似乎不起作用
it = np.nditer(a, flags=['multi_index'])
while not it.finished:
it[...] = . . .
it.iternext()
然而,我能够使用 it.multi_index
值,但它似乎不必要地冗长。有没有更简单的方法来实现这一点,通过不同的方法或不同的语法?
it = np.nditer(a, flags=['multi_index'])
while not it.finished:
matrix[it.multi_index[0]][it.multi_index[1]] = . . .
it.iternext()
编辑
这是一个 multi_index
迭代尝试使用迭代器索引修改值但失败的示例。
matrix = np.zeros((5,5))
it = np.nditer(matrix, flags=['multi_index'])
while not it.finished:
it[...] = 1
it.iternext()
产生的错误是
TypeError Traceback (most recent call last)
<ipython-input-79-3f4cabcbfde6> in <module>()
25 it = np.nditer(matrix, flags=['multi_index'])
26 while not it.finished:
---> 27 it[...] = 1
28 it.iternext()
TypeError: invalid index type for iterator indexing
在您的第一个迭代示例中:
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 <class 'numpy.ndarray'>
1 <class 'numpy.ndarray'>
2 <class 'numpy.ndarray'>
3 <class 'numpy.ndarray'>
4 <class 'numpy.ndarray'>
....
11 <class 'numpy.ndarray'>
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
的元素进行相同的迭代,但也会生成二维索引元组。 it
是 nditer
对象,具有各种方法和属性。在本例中,它有一个 multi_index
属性。而当前迭代变量在it[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
对象,并使用 while not finished
语法进行迭代。而不是访问 x[...]
我必须使用 it[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
代码中使用它的垫脚石,它是最有用的。请参阅迭代页面的最终示例。
我有一个二维数组,我正在迭代它以努力使用索引值进行计算,然后将计算出的值分配给所述索引。
在 NumPy 文档中,an example 提供了使用迭代器修改值的方法:
for x in np.nditer(a, op_flags=['readwrite']):
x[...] = 2 * x
但是,当使用 the following method:
跟踪索引时,这似乎不起作用it = np.nditer(a, flags=['multi_index'])
while not it.finished:
it[...] = . . .
it.iternext()
然而,我能够使用 it.multi_index
值,但它似乎不必要地冗长。有没有更简单的方法来实现这一点,通过不同的方法或不同的语法?
it = np.nditer(a, flags=['multi_index'])
while not it.finished:
matrix[it.multi_index[0]][it.multi_index[1]] = . . .
it.iternext()
编辑
这是一个 multi_index
迭代尝试使用迭代器索引修改值但失败的示例。
matrix = np.zeros((5,5))
it = np.nditer(matrix, flags=['multi_index'])
while not it.finished:
it[...] = 1
it.iternext()
产生的错误是
TypeError Traceback (most recent call last)
<ipython-input-79-3f4cabcbfde6> in <module>()
25 it = np.nditer(matrix, flags=['multi_index'])
26 while not it.finished:
---> 27 it[...] = 1
28 it.iternext()
TypeError: invalid index type for iterator indexing
在您的第一个迭代示例中:
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 <class 'numpy.ndarray'>
1 <class 'numpy.ndarray'>
2 <class 'numpy.ndarray'>
3 <class 'numpy.ndarray'>
4 <class 'numpy.ndarray'>
....
11 <class 'numpy.ndarray'>
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
的元素进行相同的迭代,但也会生成二维索引元组。 it
是 nditer
对象,具有各种方法和属性。在本例中,它有一个 multi_index
属性。而当前迭代变量在it[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
对象,并使用 while not finished
语法进行迭代。而不是访问 x[...]
我必须使用 it[0][...]
.
np.ndindex
是一种更方便的生成 multi_index
的方法。看它的代码。它是为数不多的使用 np.nditer
.
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
代码中使用它的垫脚石,它是最有用的。请参阅迭代页面的最终示例。