下面的x[...]
是什么意思?
a = np.arange(6).reshape(2,3)
for x in np.nditer(a, op_flags=['readwrite']):
x[...] = 2 * x
最佳答案
虽然建议的重复What does the Python Ellipsis object do?在一般python
上下文中回答了该问题,但我认为在nditer
循环中使用它需要添加信息。
https://docs.scipy.org/doc/numpy/reference/arrays.nditer.html#modifying-array-values
该部分包括您的代码示例。
用我的话来说,x[...] = ...
就地修改了x
; x = ...
将破坏指向nditer
变量的链接,并且不会对其进行更改。就像x[:] = ...
一样,但是可以处理任何维度(包括0d)的数组。在这种情况下,x
不只是一个数字,而是一个数组。
如果不添加nditer
,则最接近此nditer
迭代的事情可能是:
In [667]: for i, x in np.ndenumerate(a):
...: print(i, x)
...: a[i] = 2 * x
...:
(0, 0) 0
(0, 1) 1
...
(1, 2) 5
In [668]: a
Out[668]:
array([[ 0, 2, 4],
[ 6, 8, 10]])
注意,我必须直接索引和修改
a[i]
。我不能使用x = 2*x
。在此迭代中,x
是标量,因此不可变In [669]: for i,x in np.ndenumerate(a):
...: x[...] = 2 * x
...
TypeError: 'numpy.int32' object does not support item assignment
但是在
nditer
情况下,x
是一个0d数组,并且是可变的。In [671]: for x in np.nditer(a, op_flags=['readwrite']):
...: print(x, type(x), x.shape)
...: x[...] = 2 * x
...:
0 <class 'numpy.ndarray'> ()
4 <class 'numpy.ndarray'> ()
...
并且因为它是0d,所以不能使用
x[:]
代替x[...]
----> 3 x[:] = 2 * x
IndexError: too many indices for array
一个更简单的数组迭代可能还会提供一些见解:
In [675]: for x in a:
...: print(x, x.shape)
...: x[:] = 2 * x
...:
[ 0 8 16] (3,)
[24 32 40] (3,)
这会在
a
的行(第1个昏暗)上进行迭代。 x
是一维数组,可以使用x[:]=...
或x[...]=...
进行修改。如果我从下一个section中添加
external_loop
标志,则x
现在是一维数组,并且x[:] =
将起作用。但是x[...] =
仍然有效并且更通用。 x[...]
用于所有其他nditer
示例。In [677]: for x in np.nditer(a, op_flags=['readwrite'], flags=['external_loop']):
...: print(x, type(x), x.shape)
...: x[...] = 2 * x
[ 0 16 32 48 64 80] <class 'numpy.ndarray'> (6,)
比较这个简单的行迭代(在二维数组上):
In [675]: for x in a:
...: print(x, x.shape)
...: x[:] = 2 * x
...:
[ 0 8 16] (3,)
[24 32 40] (3,)
这会在
a
的行(第1个昏暗)上进行迭代。 x
是一维数组,可以使用x[:] = ...
或x[...] = ...
进行修改。从头到尾阅读并尝试使用
nditer
页面。就其本身而言,nditer
在python
中不是那么有用。它不会加快迭代速度-除非您将代码移植到 cython
。 np.ndindex
是使用numpy
的少数几个未编译nditer
函数之一。