Was macht die Indizierung eines Arrays mit dem leeren Tupel im Vergleich zu den Ellipsen?

9

Ich habe zufällig entdeckt, dass ein Array in numpy durch ein leeres Tupel indiziert werden kann:

%Vor%

Ich habe eine Dokumentation über das numpy wiki ZeroRankArray gefunden:

  

(Sasha) Erstens, was auch immer für x [...] und x [()] gewählt wird, sie sollten gleich sein, denn ... ist nur syntaktischer Zucker für "so viele: wie nötig", was in der Der Fall von Nullrang führt zu ... = (:,) * 0 = (). Zweitens sind Rang-Nullenarrays und Numpy-Skalartypen innerhalb von Numpy austauschbar, aber Numpy-Skalare können in einigen Python-Konstrukten verwendet werden, wo NDarrays dies nicht können.

Also, für 0-d-Arrays sollen a[()] und a[...] gleichwertig sein. Sind sie auch für höherdimensionale Arrays? Sie scheinen stark zu sein:

%Vor%

Aber ist es nicht syntaktischer Zucker. Nicht für ein hochdimensionales Array und nicht einmal für ein 0-d-Array:

%Vor%

Und dann gibt es den Fall der Indizierung durch eine leere Liste , die etwas ganz anderes tut, aber der Indexierung mit einem leeren ndarray :

gleichkommt %Vor%

So scheint es, dass () und ... ähnlich aber nicht ganz identisch sind und die Indizierung mit [] etwas ganz anderes bedeutet. Und a[] oder b[] sind SyntaxError s. Die Indizierung mit Listen ist in Indexarrays dokumentiert, und es gibt einen kurzen Hinweis Hinweis zur Indizierung mit Tupel at das Ende desselben Dokuments .

Das lässt die Frage:

Ist der Unterschied zwischen a[()] und a[...] von Entwurf? Was ist das Design?

(Frage erinnert irgendwie an: Was macht das leere '()' auf einer Matlab-Matrix? )

Bearbeiten:

Tatsächlich können sogar Skalare durch ein leeres Tupel indiziert werden:

%Vor%     
gerrit 04.02.2013, 14:51
quelle

2 Antworten

6

Die Behandlung von A[...] ist ein Spezialfall, optimiert für gib immer A selbst zurück :

%Vor%

Alles andere, das äquivalent sein sollte, z.B. A[:] , A[(Ellipsis,)] , A[()] , A[(slice(None),) * A.ndim] gibt stattdessen eine Ansicht der Gesamtheit von A zurück, deren base ist A :

%Vor%

Dies scheint eine unnötige und vorzeitige Optimierung zu sein, da A[(Ellipsis,)] und A[()] immer das gleiche Ergebnis liefern (eine gesamte Sicht auf A ). Aus dem Blick auf Ссылка scheint es, dass es ursprünglich erforderlich war, weil die Indizierung mit ... auf 0d nicht richtig funktionierte Arrays (zuvor zu Ссылка würde es das Element als Skalar zurückgeben), dann aus Konsistenzgründen auf alle Arrays erweitert; Seither wurde die Indexierung auf 0d-Arrays fixiert, so dass die Optimierung nicht erforderlich ist, aber es ist gelungen, sich rudimentär zu verhalten (und es gibt wahrscheinlich Code, der davon abhängt, dass A[...] is A wahr ist).

    
ecatmur 04.02.2013, 18:12
quelle
4

Während in dem Beispiel, das Sie angegeben haben, das leere Tupel und die Ellipse ein ähnliches Ergebnis liefern, dienen sie im Allgemeinen unterschiedlichen Zwecken. Wenn ein Array indiziert wird, A[i, j, k] == A[(i, j, k)] und speziell A[...] == A[(Ellipsis,)] . Hier dient das Tupel einfach als Container für Indexierungselemente. Dies kann nützlich sein, wenn Sie den Index als Variable bearbeiten müssen, zum Beispiel:

%Vor%

Beachten Sie, dass das Tupel der Container für die Indizierung von Elementen ist und nicht mit anderen Indizes kombiniert werden kann, z. B. A[(), 0] == A[[], 0] und A[(), 0] != A[..., 0] .

Da ein Array A mit weniger Indizes als A.ndim indexiert werden kann, ist die Indizierung mit einem leeren Tupel eine natürliche Erweiterung dieses Verhaltens und kann in manchen Situationen nützlich sein, zum Beispiel funktioniert der obige Code-Snipit A.ndim == 0 .

Kurz gesagt, das Tupel dient als Container für Indexelemente, die leer sein dürfen, während die Ellipse eines der möglichen Indexierungselemente ist.

    
Bi Rico 04.02.2013 17:38
quelle

Tags und Links