Ich möchte ein NumPy nxn-Array in Scheiben schneiden. Ich möchte eine beliebige Auswahl von m Zeilen und Spalten dieses Arrays extrahieren (dh ohne Muster in der Anzahl der Zeilen / Spalten), wodurch es zu einem neuen mxm-Array wird. Nehmen wir für dieses Beispiel an, das Array ist 4x4 und ich möchte ein 2x2-Array daraus extrahieren.
Hier ist unser Array:
from numpy import *
x = range(16)
x = reshape(x,(4,4))
print x
[[ 0 1 2 3]
[ 4 5 6 7]
[ 8 9 10 11]
[12 13 14 15]]
Die zu entfernenden Zeilen und Spalten sind identisch. Der einfachste Fall ist, wenn ich eine 2x2-Submatrix extrahieren möchte, die am Anfang oder am Ende steht, dh:
In [33]: x[0:2,0:2]
Out[33]:
array([[0, 1],
[4, 5]])
In [34]: x[2:,2:]
Out[34]:
array([[10, 11],
[14, 15]])
Aber was ist, wenn ich eine andere Mischung aus Zeilen / Spalten entfernen muss? Was ist, wenn ich die erste und dritte Zeile / Zeile entfernen muss, um die Submatrix zu extrahieren [[5,7],[13,15]]
? Es kann eine beliebige Zusammensetzung von Zeilen / Zeilen geben. Ich habe irgendwo gelesen, dass ich mein Array nur mit Arrays / Indexlisten für Zeilen und Spalten indizieren muss, aber das scheint nicht zu funktionieren:
In [35]: x[[1,3],[1,3]]
Out[35]: array([ 5, 15])
Ich habe einen Weg gefunden, nämlich:
In [61]: x[[1,3]][:,[1,3]]
Out[61]:
array([[ 5, 7],
[13, 15]])
Das erste Problem dabei ist, dass es kaum lesbar ist, obwohl ich damit leben kann. Wenn jemand eine bessere Lösung hat, würde ich sie sicherlich gerne hören.
Eine andere Sache ist, dass ich in einem Forum gelesen habe , dass das Indizieren von Arrays mit Arrays NumPy zwingt, eine Kopie des gewünschten Arrays zu erstellen. Bei der Behandlung mit großen Arrays kann dies daher zu einem Problem werden. Warum ist das so / wie funktioniert dieser Mechanismus?
x[[[1],[3]],[1,3]]
nur ein neues Array, während esx[[1,3],:][:,[1,3]]
zweimal kopiert wird. Verwenden Sie also das erste.Ich denke nicht, dass
x[[1,3]][:,[1,3]]
das kaum lesbar ist. Wenn Sie Ihre Absichten klarer formulieren möchten, können Sie Folgendes tun:Ich bin kein Experte für das Schneiden, aber wenn Sie versuchen, in ein Array zu schneiden und die Werte kontinuierlich sind, erhalten Sie normalerweise eine Ansicht zurück, in der der Schrittwert geändert wird.
Beispiel: In Ihren Eingaben 33 und 34 beträgt der Schritt 4, obwohl Sie ein 2x2-Array erhalten. Wenn Sie also die nächste Zeile indizieren, bewegt sich der Zeiger an die richtige Position im Speicher.
Es ist klar, dass dieser Mechanismus bei einer Reihe von Indizes nicht gut funktioniert. Daher muss numpy die Kopie erstellen. Schließlich hängen viele andere mathematische Matrixfunktionen von Größe, Schritt und kontinuierlicher Speicherzuweisung ab.
quelle
Wenn Sie jede zweite Zeile und jede zweite Spalte überspringen möchten, können Sie dies mit einem einfachen Slicing tun:
Dies gibt eine Ansicht zurück, keine Kopie Ihres Arrays.
while
z=x[(1,3),:][:,(1,3)]
verwendet die erweiterte Indizierung und gibt somit eine Kopie zurück:Beachten Sie, dass dies
x
unverändert bleibt:Wenn Sie beliebige Zeilen und Spalten auswählen möchten, können Sie kein einfaches Slicing verwenden. Sie müssen die erweiterte Indizierung verwenden und dabei Sequenzen wie
x[rows,:][:,columns]
, worows
undcolumns
sind verwenden. Dadurch erhalten Sie natürlich eine Kopie und keine Ansicht Ihres ursprünglichen Arrays. Dies ist zu erwarten, da ein Numpy-Array zusammenhängenden Speicher (mit konstanten Schritten) verwendet und es keine Möglichkeit gibt, eine Ansicht mit beliebigen Zeilen und Spalten zu generieren (da dies nicht konstante Schritte erfordern würde).quelle
Mit numpy können Sie für jede Komponente des Index ein Slice übergeben - also Ihr
x[0:2,0:2]
obige Beispiel funktioniert also.Wenn Sie nur Spalten oder Zeilen gleichmäßig überspringen möchten, können Sie Slices mit drei Komponenten übergeben (z. B. Start, Stopp, Schritt).
Nochmals für Ihr Beispiel oben:
Das heißt im Grunde: Slice in der ersten Dimension mit Start bei Index 1, Stop, wenn der Index gleich oder größer als 4 ist, und addiere 2 zum Index in jedem Durchgang. Gleiches gilt für die zweite Dimension. Nochmals: Dies funktioniert nur für konstante Schritte.
Die Syntax, mit der Sie intern etwas ganz anderes tun müssen -
x[[1,3]][:,[1,3]]
tatsächlich wird ein neues Array erstellt, das nur die Zeilen 1 und 3 des ursprünglichen Arrays enthält (mit demx[[1,3]]
Teil fertig ), und das dann neu geschnitten - ein drittes Array erstellt - nur eingeschlossen Spalten 1 und 3 des vorherigen Arrays.quelle
Ich habe hier eine ähnliche Frage: Schreiben in Sub-Ndarray eines Ndarray auf pythonischste Weise. Python 2 .
Nach der Lösung des vorherigen Beitrags für Ihren Fall sieht die Lösung folgendermaßen aus:
Ein using ix_:
Welches ist:
quelle
Ich bin nicht sicher, wie effizient dies ist, aber Sie können range () verwenden, um in beide Achsen zu schneiden
quelle