web-dev-qa-db-ja.com

数字のように見えるものにインデックスを付けるとき、Pythonの「3つのドット」とはどういう意味ですか?

以下のx [...]の意味は何ですか?

a = np.arange(6).reshape(2,3)
for x in np.nditer(a, op_flags=['readwrite']):
    x[...] = 2 * x
52
Nan Hua

提案された複製 Python Ellipsisオブジェクトは何をしますか? は一般的なpythonコンテキストで質問に答え、nditerループには情報を追加する必要があると思います。

https://docs.scipy.org/doc/numpy/reference/arrays.nditer.html#modifying-array-values

Pythonの通常の割り当ては、既存の変数をその場で変更するのではなく、ローカルまたはグローバル変数辞書の参照を単に変更します。これは、単にxに割​​り当てると、値が配列の要素に配置されず、xが配列要素の参照から割り当てた値への参照に切り替わることを意味します。配列の要素を実際に変更するには、xに省略記号を付ける必要があります。

そのセクションにはコード例が含まれています。

したがって、私の言葉では、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の行(最初のdim)で繰り返します。 xは1D配列であり、x[:]=...またはx[...]=...で変更できます。

そして、次の section セクションからexternal_loopフラグを追加すると、xは1d配列になり、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,)

この単純な行の繰り返しを比較します(2次元配列で):

In [675]: for x in a:
     ...:     print(x, x.shape)
     ...:     x[:] = 2 * x
     ...:     
[ 0  8 16] (3,)
[24 32 40] (3,)

これは、aの行(最初のdim)で繰り返します。 xは1D配列であり、x[:] = ...またはx[...] = ...で変更できます。

このnditerページを最後まで読んで実験してください。 nditer自体は、pythonではあまり役に立ちません。コードを cython に移植するまでではありません-np.ndindexは、コンパイルされていない数少ないnumpy関数の1つですnditerを使用します。

44
hpaulj