Ich habe eine np.array data
Form (28,8,20), und ich brauche nur bestimmte Einträge davon, also nehme ich ein Stück:
So weit, so gut, alles so wie es sein sollte. Aber jetzt möchte ich nur die ersten zwei Einträge auf dem letzten Index für die erste Zeile betrachten:
%Vor%Warte, das sollte (8,2) sein. Es hat die Indizes umgestellt, obwohl es beim letzten Schneiden nicht passiert ist! Meines Erachtens sollte das Folgende genauso funktionieren:
%Vor%... aber es gibt mir genau das, was ich wollte! Solange ich ein 3D-Array habe, scheinen beide Methoden gleich zu sein:
%Vor%Was mache ich also, wenn ich nicht nur die ersten beiden Einträge sondern eine unregelmäßige Liste haben möchte? Ich könnte natürlich die Matrix nach der Operation transponieren, aber das scheint sehr kontraintuitiv zu sein. Eine bessere Lösung für mein Problem ist dies (obwohl es eine elegantere geben könnte):
%Vor%Was uns zum eigentlichen
bringtIch frage mich, was der Grund für dieses Verhalten ist? Wer auch immer entschieden hat, dass es so funktionieren sollte, wusste wahrscheinlich mehr über Programmierung als ich und dachte, dass dies in gewisser Weise konsistent ist, die ich völlig vermisse. Und ich werde wahrscheinlich weiterhin meinen Kopf darüber schlagen, es sei denn, ich habe eine Möglichkeit, einen Sinn daraus zu machen.
Dies ist ein Fall von (fortgeschrittener) partieller Indizierung. Es gibt 2 indizierte Arrays und 1 Slice
Wenn die Indizierungsunterräume getrennt sind (nach Segmentobjekten), wird zuerst der gesendete Indizierungsraum gefolgt von dem in Unterteilungen unterteilten Bereich von x.
Das Beispiel für erweiterte Indexerstellung zeigt an, dass der untergeordnete Teilbereich ind_1
, ind_2
% shape (2,3,4)
ist:
Allerdings hat x [:, ind_1,:, ind_2] eine Form (2,3,4,10,30,50), weil es keine eindeutige Stelle gibt, an der der Unterraum für die Indexierung abgelegt werden kann, also angeheftet wird der Anfang. Es ist immer möglich, .transpose () zu verwenden, um den Unterraum beliebig zu verschieben.
Mit anderen Worten, diese Indizierung ist nicht dasselbe wie x[:, ind_1][[:,ind_2]
. Die 2 Arrays arbeiten gemeinsam, um einen (2,3,4)
Unterraum zu definieren.
In Ihrem Beispiel wird extract[0,:,np.array([0,1])]
so verstanden, dass Sie einen (2,)
Unterraum wählen (die [0] und [0,1] wirken gemeinsam, nicht sequentiell) und kombinieren das irgendwie mit der mittleren Dimension.
Ein komplizierteres Beispiel wäre extract[[1,0],:,[[0,1],[1,0]]]
, das ein (2,2,8)
-Array erzeugt. Dies ist ein (2,2)
Unterraum der ersten und letzten Dimensionen plus der mittleren. Auf der anderen Seite erzeugt X[[1,0]][:,:,[[0,1],[1,0]]]
eine (2,8,2,2)
, die aus der ersten und letzten Dimension getrennt ausgewählt wird.
Der Hauptunterschied besteht darin, ob die indizierten Selektionen sequentiell oder gemeinsam ausgeführt werden. Die '[...] [...] Syntax ist bereits verfügbar, um sequentiell zu arbeiten. Erweiterte Indexierung gibt Ihnen eine Möglichkeit, gemeinsam zu indexieren.
Sie haben Recht, das ist komisch. Ich kann hier nur raten. Ich denke, das hängt damit zusammen, dass a[[0,1],[0,1],[0,1]].shape
eher (2,)
als (2,2,2)
ist und dass a[0,1,[0,1,2]]
wirklich a[[0,0,0],[1,1,1],[0,1,2]]
bedeutet, was zu array([a[0,1,0],a[0,1,1],a[0,1,2]])
führt. Das heißt, Sie durchlaufen die Listen als Indizes für jede Dimension parallel, wobei Listen der Länge eins und Skalare ausgesendet werden, die der längsten entsprechen.
Vom Konzept her würde das Ihre extract[0,:,[0,1]]
zu extract[[0,0],[slice(None),slice(None)],[0,1]]
äquivalent machen (diese Syntax wird jedoch nicht akzeptiert, wenn Sie sie manuell angeben). Nach dem Durchlaufen der Indizes würde dies zu array([extract[0,slice(None),0],extract[0,slice(None),1])
ausgewertet werden. Jeder der inneren Extrakte wird in ein Array mit der Form (8,)
ausgewertet. Das vollständige Ergebnis lautet also shape (2,8)
.
Zum Schluss denke ich, dass es ein Nebeneffekt des Broadcastings ist, dass alle Dimensionen eine Indexliste gleicher Länge haben, was dazu führt, dass auch :
ausgestrahlt wird. Das ist meine Hypothese, aber ich habe nicht die innere Funktionsweise von numpy
untersucht. Vielleicht kommt ein Experte mit einer besseren Erklärung.
Diese Hypothese erklärt nicht, warum extract[:,:,[0,1]]
nicht zum selben Verhalten führt. Ich würde postulieren müssen, dass der Fall, dass nur ":" als Spezialfall geführt wird, um die Teilnahme an der Listenindexlogik zu vermeiden.