下面的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[...] = ...就地修改了xx = ...将破坏指向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页面。就其本身而言,nditerpython中不是那么有用。它不会加快迭代速度-除非您将代码移植到 cython np.ndindex是使用numpy的少数几个未编译nditer函数之一。

10-06 13:27