Blick auf ein numpy Array?


89

Ich habe ein 2D- numpyArray. Gibt es eine Möglichkeit, eine Ansicht darauf zu erstellen, die die ersten kZeilen und alle Spalten enthält?

Es geht darum, das Kopieren der zugrunde liegenden Daten zu vermeiden (das Array ist so groß, dass Teilkopien nicht möglich sind).

Antworten:


225

Sicher, indizieren Sie es einfach wie gewohnt. Beispiel: y = x[:k, :] Dies gibt eine Ansicht in das ursprüngliche Array zurück. Es werden keine Daten kopiert und vorgenommene Aktualisierungen ywerden in xund umgekehrt wiedergegeben.


Bearbeiten:

Ich arbeite normalerweise mit> 10 GB 3D-Arrays von uint8, daher mache ich mir große Sorgen ... Numpy kann bei der Speicherverwaltung sehr effizient sein, wenn Sie einige Dinge beachten. Hier einige Tipps, wie Sie das Kopieren von Arrays im Speicher vermeiden können:

Verwenden Sie +=, -=, *=usw. zu vermeiden , dass eine Kopie des Arrays zu machen. ZB x += 10wird das Array an Ort x = x + 10und Stelle geändert , während eine Kopie erstellt und geändert wird. (Schauen Sie sich auch numexpr an. )

Wenn Sie eine Kopie mit x = x + 10erstellen möchten , beachten Sie, x = x + 10.0dass xdiese automatisch in ein Gleitkomma-Array umgewandelt wird, sofern dies noch nicht geschehen ist. Jedoch x += 10.0, in dem xeine ganze Zahl Array, bewirkt , dass der 10.0gegossen unten zu sein in einen int der gleichen Präzision wie die Anordnung, statt.

Darüber hinaus verwenden viele Numpy-Funktionen einen outParameter, sodass Sie beispielsweise np.abs(x, x)den absoluten Wert von xin-place verwenden können.


Als zweite Bearbeitung finden Sie hier einige weitere Tipps zu Ansichten und Kopien mit numpy Arrays:

Im Gegensatz zu Python-Listen wird y = x[:]keine Kopie zurückgegeben, sondern eine Ansicht. Wenn Sie eine Kopie wünschen (die natürlich die Menge des verwendeten Speichers verdoppelt), verwenden Sie diesey = x.copy()

Sie werden oft von "Fancy Indexing" von Numpy-Arrays hören. Die Verwendung einer Liste (oder eines Integer-Arrays) als Index ist "ausgefallene Indizierung". Es kann sehr nützlich sein, kopiert aber die Daten.

Als Beispiel hierfür: y = x[[0, 1, 2], :]Gibt eine Kopie zurück, während y = x[:3,:]eine Ansicht zurückgegeben wird.

Selbst eine wirklich verrückte Indizierung x[4:100:5, :-10:-1, None]ist eine "normale" Indizierung und gibt eine Ansicht zurück. Haben Sie also keine Angst davor, bei großen Arrays alle Arten von Slicing-Tricks anzuwenden.

x.astype(<dtype>)gibt eine Kopie der Daten als neuen Typ zurück, während x.view(<dtype>)eine Ansicht zurückgegeben wird.

Seien Sie jedoch vorsichtig damit ... Es ist äußerst leistungsfähig und nützlich, aber Sie müssen verstehen, wie die zugrunde liegenden Daten im Speicher gespeichert werden. Wenn Sie ein Array von Floats haben und diese als Ints anzeigen (oder umgekehrt), interpretiert numpy die zugrunde liegenden Bits des Arrays als Ints.

Dies bedeutet beispielsweise, dass 1.0ein 64-Bit-Float auf einem Little-Endian-System 4607182418800017408als 64-Bit-Int und ein Array von [ 0, 0, 0, 0, 0, 0, 240, 63]als Uint8 betrachtet wird. Dies ist sehr hilfreich, wenn Sie auf großen Arrays eine Art Bit-Twiddling durchführen müssen ... Sie haben nur eine geringe Kontrolle darüber, wie der Speicherpuffer interpretiert wird.


Danke für die sehr schönen Tipps! Ich habe das Numpy-Benutzerhandbuch gelesen und war verwirrt, warum es x[np.array([1, 1, 3, 1])] += 1geändert wurde x. Jetzt verstanden!
tnq177

nette tipps! Ich habe eine andere Frage. Wie kann man beweisen, dass Numpy keine Kopie, sondern nur eine Ansicht auslöst? Pythons ID () scheint dazu nicht in der Lage zu sein.
Wuhaochi

3
@wuhaochi Wenn bist eine Ansicht von a, dann b.base is awird sein True. Eine Kopie (eines beliebigen Arrays) wird immer habenarr_copy.base is None
Jürg Merlin Spaak
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.