Pythonでは省略記号のスライス構文をどのように使用しますか?


回答:


102

Ellipsis、または...隠し機能ではありません。それは単なる定数です。言語構文の一部であるjavascript ES6などとはかなり異なります。組み込みのクラスやPython言語の構築ではこれを利用していません。

そのため、その構文は、それを理解するためのコードを書いたかどうかに依存します。

ドキュメントに記載されているように、Numpyはそれを使用しますここにいくつかの例があります

自分のクラスでは、次のように使用します。

>>> class TestEllipsis(object):
...     def __getitem__(self, item):
...         if item is Ellipsis:
...             return "Returning all items"
...         else:
...             return "return %r items" % item
... 
>>> x = TestEllipsis()
>>> print x[2]
return 2 items
>>> print x[...]
Returning all items

もちろん、Pythonのドキュメント言語リファレンスがあります。しかし、それらはあまり役に立ちません。


6
すべてのアイテムを言う「適切な」方法が>>> x [:] >>> x [:, 1:2]であるため、かなり壊れているように見えます
Ronny

30
@Ronny:ポイントは、Ellipsisのカスタム使用法を示すことでした。
nosklo 2009年

7
リンクが壊れているようです。
SwiftsNamesake

229

省略記号は、高次元のデータ構造をスライスするためにnumpyで使用されます。

これは、この時点で、:多次元スライスをすべての次元に拡張するために完全なスライス()を挿入することを意味するように設計されています

>>> from numpy import arange
>>> a = arange(16).reshape(2,2,2,2)

これで、2x2x2x2の4次元行列ができました。4次元のすべての最初の要素を選択するには、省略記号表記を使用できます

>>> a[..., 0].flatten()
array([ 0,  2,  4,  6,  8, 10, 12, 14])

これは

>>> a[:,:,:,0].flatten()
array([ 0,  2,  4,  6,  8, 10, 12, 14])

独自の実装では、上記のコントラクトを無視して自由に使用できます。


多分私は間違っていますが、それa[:,:,:,0]はコピーを返し、コピーでa[...,0]はなく「ビュー」を返すでしょうか?私はid()両方のバージョンと3次元配列に対して実行してみました: a[:,:,:, 0], a[:,:,:, 1], a[:,:,:, 2] すべてが異なるIDをa[..., 0], a[..., 1], a[..., 2] 持っているのに対し、:すべてが同じIDを持っています。
mohitsharma44

私のマシンにない@ mohitsharma44;)id()両方に対して同じ値を返します。また、で確認すると__array_interface__['data']、同じメモリアドレスが表示されます。
BoltzmannBrain

a[indexes, ...]aが1次元配列でも使用できることがわかりました!
加害者、2017年

1
楕円は、ゼロ次元のデータ構造にも役立ちます。これらは、スカラーnumpy.ndarraysに書き込むために私が知っている唯一の方法です。例:my_scalar = np.asarray(3); my_scalar [...] = 5. my_scalar [:] = 5を実行すると、:を反復するための次元0がないため、エラーが発生します。
SuperElectric 2018

1
@SuperElectric my_scalar.itemset(scalarvalue)を使用することもできます。もちろん、my_scalar [...] = scalar_valueの方が短いですが、上記のコメントで、これが唯一の方法であることを説明しました。代わりを与えるだけです。
kamathln 2018年

70

これは、Ellipsisのもう1つの使用法であり、スライスとは関係ありません。キューとのスレッド内通信で、「完了」を示すマークとしてよく使用します。それはそこにあり、オブジェクトであり、シングルトンであり、その名前は「不足」を意味し、過度に使用されたNoneではありません(通常のデータフローの一部としてキューに入れられる可能性があります)。YMMV。


14
どこかで "Done = object()"と言ってそれを使うだけの方が明確ではないでしょうか?
Brandon Rhodes、

12
必ずしもそうとは限りません。実際にどこかでDone = object()と言う必要があります。歩哨の値は必ずしも悪いことではありません。歩哨としてほとんど役に立たないPythonシングルトンを使用することは、それほど恐ろしいIMOではありません(省略記号と()は、Noneが混乱を招く場合に使用したものです)。
Rick Copeland

6
Done = object()に関しては、特にキューとの通信にEllipsisを使用している場合は、Ellipsisを使用する方が良いと思います。スレッド内からプロセス内通信に移行する場合、id(Done)は他のプロセスと同じにならず、オブジェクトを区別するものはありません。EllipsisのIDも同じではありませんが、少なくともタイプは同じです-これがシングルトンのポイントです。
トリスタンリード

「省略記号はどのように使用するのですか」という質問ですが、これは間違った方法で行ったと思います。多くの解釈があります。しかし、私は正しいと思います:「エリプシスはどのように使用されますか?」つまり、「自分のコードでEllipsisを使用するには、どのような手順を踏む必要がありますか」。
リンドンホワイト

6

他の回答で述べたように、スライスの作成に使用できます。多くの完全なスライス表記(:)を記述したくない場合、または操作される配列の次元数がわからない場合に役立ちます。

私が強調することが重要だと思ったのは、他の答えでは見当たらないことですが、埋める必要のある次元がなくなった場合でも使用できるということです。

例:

>>> from numpy import arange
>>> a = arange(4).reshape(2,2)

これはエラーになります:

>>> a[:,0,:]
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
IndexError: too many indices for array

これは動作します:

a[...,0,:]
array([0, 1])
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.