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


90

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

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

1
それはリストではありません。
user2357112は、2017


1
これを理解する必要があり楽しい方法はジェームズ・パウエルの話ですyoutube.com/watch?v=65_-6kEAq58
SARose

回答:


70

提案された複製の間、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,)

これは、の行(1番目の薄暗い)で繰り返されaます。 xその場合、は1d配列であり、x[:]=...またはのいずれかで変更できますx[...]=...

そして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,)

この単純な行の反復を(2D配列で)比較します。

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

これは、の行(1番目の薄暗い)で繰り返されaます。 xその場合、は1d配列であり、x[:] = ...またはのいずれかで変更できますx[...] = ...

このnditerページを最後まで読んで試してみてください。それ自体でnditerは、ではそれほど役に立ちませんpython。コードをに移植するまで、反復は高速化されませんcython。を使用np.ndindexする数少ない非コンパイルnumpy関数の1つですnditer


x [1、:、...]のようなものも許可された構文であることに注意してください。将来の参考のために残しました。
borgr
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.