Numpy: Das Indizierungsverhalten mit Ellipsen ist nicht intuitiv.

Erstellt am 27. Juli 2020  ·  6Kommentare  ·  Quelle: numpy/numpy

Die Array-Indizierung mit Ellipsen kann äußerst kontraintuitiv sein. Im folgenden Beispiel ändert beispielsweise die Einführung redundanter Ellipsen die Form der Ausgabe:

a = np.array([[[False]]])
a[0:0, 0, ..., [0]]
Out[23]: array([], shape=(1, 0), dtype=bool)
a[0:0, 0,  [0]]
Out[24]: array([], shape=(0, 1), dtype=bool)

Ich denke nicht, dass dies das gewünschte Verhalten ist, aber es scheint direkt aus Entwurfsentscheidungen hinsichtlich des Umgangs mit komplexer Indizierung zu stammen .

Numpy / Python-Versionsinformationen:

1.17.3 3.7.5 (Standard, 25. Oktober 2019, 10:52:18)
[Clang 4.0.1 (tags / RELEASE_401 / final)]

04 - Documentation 33 - Question 57 - Close?

Hilfreichster Kommentar

Ich stimme zu, dass dies alles verwirrend ist, und ich wäre nicht einmal sicher gewesen, ohne zu überprüfen, was hier passiert. Aber es scheint mir die richtige Wahl zu sein.

Warum sollte es wirklich "unsichtbar" sein? ... sollte sich für eine beliebige Anzahl von Dimensionen identisch verhalten. Dazu muss in jedem Fall die Transponierung ausgelöst werden. Das heißt, stellen Sie sich etwas vor, das als series, ..., color wobei ... benutzerdefiniert ist und 0-d sein kann. Wenn Sie ein Programm schreiben würden, um diese Daten zu verarbeiten, müsste die Indizierung vorhersehbar transponiert werden, unabhängig davon, wohin ... erweitert (oder nicht erweitert) wird.

Am Ende ist dies einfach verwirrend, und wir müssten .oindex und .vindex usw. ernsthafter aufgreifen, um das Problem zu beheben: https://numpy.org/neps/nep- 0021-advanced-indexing.html

Alle 6 Kommentare

Dies sieht nach einem besonders bösen Eckfall aus - ich denke, wir betrachten die ... als Zwang, die beiden fortgeschrittenen Indizes 0 und [0] als nicht benachbart zu betrachten - obwohl Die Achsen, die sie indizieren, sind benachbart.

Dieses Problem ist aufgetreten, als wir versucht haben, die Numpy-Indizierung zu replizieren. Ich denke, das ist eine seltsame Interaktion zwischen zwei Regeln:

  • Die Ellipse erweitert sich zu einem Tupel vollständiger Slices, von denen jeder als Basisindex betrachtet wird
  • Erweiterte Indizes und Basisindizes gemischter Reihenfolge lösen eine Transponierungsoperation aus.

Dieser Sonderfall wird ausgelöst, weil ein 0-d-Tupel (wenn ... mit allen vorhandenen Indizes verwendet wird) immer noch als grundlegender Indexblock betrachtet wird, wenn es wirklich unsichtbar sein sollte.

Ich stimme zu, dass dies alles verwirrend ist, und ich wäre nicht einmal sicher gewesen, ohne zu überprüfen, was hier passiert. Aber es scheint mir die richtige Wahl zu sein.

Warum sollte es wirklich "unsichtbar" sein? ... sollte sich für eine beliebige Anzahl von Dimensionen identisch verhalten. Dazu muss in jedem Fall die Transponierung ausgelöst werden. Das heißt, stellen Sie sich etwas vor, das als series, ..., color wobei ... benutzerdefiniert ist und 0-d sein kann. Wenn Sie ein Programm schreiben würden, um diese Daten zu verarbeiten, müsste die Indizierung vorhersehbar transponiert werden, unabhängig davon, wohin ... erweitert (oder nicht erweitert) wird.

Am Ende ist dies einfach verwirrend, und wir müssten .oindex und .vindex usw. ernsthafter aufgreifen, um das Problem zu beheben: https://numpy.org/neps/nep- 0021-advanced-indexing.html

Ich bin mit @sebergs Argument, dass das aktuelle Verhalten die beste Verallgemeinerung ist. Wir könnten jedoch sichergehen, dass die Dokumente klarer sind.

Ich wusste nichts über diesen Vorschlag, danke für die Referenz @seberg!

Lassen Sie mich umformulieren, um sicherzugehen, dass ich Ihre Argumentation verstehe. Angenommen, wir bezeichnen erweiterte Indizes A und Basisindizes B und wie oben nenne ich die Neuordnung op eine (verallgemeinerte) Transponierte. In Ihrem Beispiel haben wir vier Fälle:

  • [A1, ..., A2] und [B1, ... A1] : Diese Fälle lösen die Transponierung auf [A1, A2, ....] und [A1, B1, ...] unabhängig davon, wie sich ... ausdehnt.
  • [A1, ..., B1] und [B1, ..., B2] : Diese Fälle nicht.

Diese Regeln sind konsistent, sobald Sie wissen, zu welcher Klasse (A oder B) series und color gehören, unabhängig davon, wie ... expandiert. Dies entspricht der Behandlung von ... als (möglicherweise 0-d) Block von Basisindizes. Die Behandlung des 0-d ... als Sonderfall wäre schlecht, da die Transponierung davon abhängt, ob der Benutzer ein 2-D-Array oder ein 3-oder-mehr-D übergeben hat. Ich stimme zu, dies ist ein schlechter Ort.

Meine Intuition, dass 0-d-Blöcke No-Op sein sollten, war davon abhängig, wie sich Tupel verhalten, wo für i ,

i: int
M: Tuple[int, ...]
N = ()
assert M[:i] + N + M[i:] == M

Dies steht im Widerspruch zur numpy -Indizierungskonvention, die in den oben genannten vier Fällen dazu führt, je nachdem, was i ist. Dies hat mehr mit der Transponierungsoperation selbst zu tun als mit der Behandlung von ... und ist ein Argument für den NEP21-Vorschlag.

Während der Entwicklung haben wir die Indizierung geändert und ... eingefügt, um den Code zukunftssicher zu machen und wirklich verwirrt zu sein, wenn die Formen magisch transponiert werden. Es wurde nur dadurch verschärft, dass der leere Fall ... besonders eingängig war.

Vielen Dank für Ihren Blick! Ich kann eine Dokument-PR einreichen, wenn Sie möchten.

@antonl a doc PR ist immer willkommen, hier sind viele Verbesserungen möglich.

War diese Seite hilfreich?
0 / 5 - 0 Bewertungen