Ich habe eine Variable x, die die Form hat (2,2,50,100).
Ich habe auch ein Array, y, das np.array ([0,10,20]) entspricht. Eine seltsame Sache passiert, wenn ich x [0,:,:, y] indiziere.
x = np.full((2,2,50,100),np.nan)
y = np.array([0,10,20])
print(x.shape)
(2,2,50,100)
print(x[:,:,:,y].shape)
(2,2,50,3)
print(x[0,:,:,:].shape)
(2,50,100)
print(x[0,:,:,y].shape)
(3,2,50)
Warum gibt der letzte (3,2,50) und nicht (2,50,3) aus?
Antworten:
Auf diese Weise verwendet numpy die erweiterte Indizierung, um Array-Formen zu senden. Wenn Sie a
0
für den ersten undy
für den letzten Index übergeben, sendet numpy0
die gleiche Form wiey
. Folgende Äquivalenz gilt :x[0,:,:,y] == x[(0, 0, 0),:,:,y]
. Hier ist ein BeispielDa Sie nun effektiv zwei Indexsätze übergeben, verwenden Sie die erweiterte Indexierungs-API, um (in diesem Fall) Indexpaare zu bilden.
Welches hat eine erste Dimension, die der Länge von entspricht
y
. Das sehen Sie.Schauen Sie sich als Beispiel ein Array mit 4 Dimensionen an, die im nächsten Abschnitt beschrieben werden:
x
hat eine wirklich leicht verständliche sequentielle Form, mit der wir jetzt zeigen können, was passiert ...Die erste Dimension entspricht 2 Excel-Arbeitsmappen, die zweite Dimension entspricht 3 Blättern in jeder Arbeitsmappe, die dritte Dimension entspricht 4 Zeilen pro Blatt und die letzte Dimension besteht aus 5 Werten für jede Zeile (oder Spalten pro Blatt).
Wenn man es so betrachtet und danach fragt
x[0,:,:,0]
, lautet das Sprichwort: "Geben Sie mir in der ersten Arbeitsmappe für jedes Blatt, für jede Zeile den ersten Wert / die erste Spalte."Aber jetzt mit erweiterter Indizierung können wir uns vorstellen, dass
x[(0,0,0),:,:,y]
"in der ersten Arbeitsmappe für jedes Blatt, für jede Zeile dery
th-Wert / die Spalte angegeben wird. Ok, machen Sie es jetzt für jeden Wert vony
".Wo es verrückt wird, ist, dass numpy gesendet wird, um dem zu entsprechen äußeren Dimensionen des Index-Arrays zu entsprechen. Wenn Sie also denselben Vorgang wie oben ausführen möchten, jedoch für BEIDE "Excel-Arbeitsmappen", müssen Sie keine Schleifen erstellen und verketten. Sie können ein Array einfach an die erste Dimension übergeben, es MUSS jedoch eine kompatible Form haben.
Das Übergeben einer Ganzzahl wird an gesendet
y.shape == (3,)
. Wenn Sie ein Array als ersten Index übergeben möchten, muss nur die letzte Dimension des Arrays kompatibel seiny.shape
. Das heißt, die letzte Dimension des ersten Index muss entweder 3 oder 1 sein.Eine kurze Erklärung in den Dokumenten gefunden: https://docs.scipy.org/doc/numpy/reference/arrays.indexing.html#combining-advanced-and-basic-indexing
Bearbeiten:
Aus der ursprünglichen Frage können Sie einen Einzeiler Ihres gewünschten Subslicing verwenden
x[0][:,:,y]
:Wenn Sie es jedoch versuchen , diesen Subslices zuzuweisen , müssen Sie sehr vorsichtig sein, dass Sie eine Shared-Memory-Ansicht des ursprünglichen Arrays betrachten. Andernfalls erfolgt die Zuordnung nicht zum ursprünglichen Array, sondern zu einer Kopie.
Shared Memory tritt nur auf, wenn Sie eine Ganzzahl oder ein Slice verwenden, um Ihr Array zu unterteilen, dh
x[:,0:3,:,:]
oderx[0,:,:,1:-1]
.Sowohl in Ihrer ursprünglichen Frage als auch in meinem Beispiel
y
handelt es sich weder um ein Int noch um ein Slice. Daher wird immer eine Kopie des Originals zugewiesen.ABER! Weil Ihre Array für
y
als eine Scheibe ausgedrückt werden, Sie CAN tatsächlich über eine frei belegbare Ansicht Ihres Array erhalten:Hier verwenden wir das Slice
0:21:10
, um jeden Index zu erfassen, der sich in befinden würderange(0,21,10)
. Wir müssen verwenden21
und nicht20
weil der Stopppunkt wie in derrange
Funktion vom Slice ausgeschlossen ist .Wenn Sie also ein Slice erstellen können, das Ihren Subslicing-Kriterien entspricht, können Sie eine Zuweisung vornehmen.
quelle
Es heißt
combining advanced and basic indexing
. Incombining advanced and basic indexing
numpy führen Sie zuerst die Indizierung in der erweiterten Indizierung durch und verketten / verketten Sie das Ergebnis mit der Dimension der Basisindizierung.Beispiel aus Dokumenten:
so, auf
x[0,:,:,y]
,0
undy
sind vorab Indizierung. Sie werden zusammen gesendet, um eine Dimension zu erhalten(3,)
.Dies geht
(3,)
an den Anfang der 2. und 3. Dimension zu machen(3, 2, 50)
Um zu sehen , dass die erste und letzte Dimension wirklich zusammenträgt, können Sie versuchen , Änderung
0
zu[0,1]
den Fehlern des Rundfunks zu sehenquelle