In [28]: arr = np.arange(16).reshape((2, 2, 4))
In [29]: arr
Out[29]:
array([[[ 0, 1, 2, 3],
[ 4, 5, 6, 7]],
[[ 8, 9, 10, 11],
[12, 13, 14, 15]]])
In [32]: arr.transpose((1, 0, 2))
Out[32]:
array([[[ 0, 1, 2, 3],
[ 8, 9, 10, 11]],
[[ 4, 5, 6, 7],
[12, 13, 14, 15]]])
transpose()
Was passiert, wenn wir der Funktion ein Tupel von ganzen Zahlen übergeben ?
Um genau zu sein, ist dies ein 3D-Array: Wie transformiert NumPy das Array, wenn ich das Tupel der Achsen passiere (1, 0 ,2)
? Können Sie erklären, auf welche Zeile oder Spalte sich diese Ganzzahlen beziehen? Und was sind Achsnummern im Kontext von NumPy?
0
ist die erste Achse,1
ist die zweite,2
ist die dritte usw. Deraxes
Parameter,transpose
der die neue Reihenfolge bereitstellt, in der sie angeordnet werden sollen, in Ihrem Beispiel: zuerst die zweite, dann die erste, dann die dritte.Antworten:
Um ein Array zu transponieren, tauscht NumPy einfach die Form- und Schrittinformationen für jede Achse aus. Hier sind die Schritte:
>>> arr.strides (64, 32, 8) >>> arr.transpose(1, 0, 2).strides (32, 64, 8)
Beachten Sie, dass bei der Transponierungsoperation die Schritte für Achse 0 und Achse 1 vertauscht wurden. Die Längen dieser Achsen wurden ebenfalls vertauscht (
2
in diesem Beispiel sind beide Längen angegeben ).Dazu müssen keine Daten kopiert werden. NumPy kann einfach die Darstellung des zugrunde liegenden Speichers ändern, um das neue Array zu erstellen.
Schritte visualisieren
Der Schrittwert gibt die Anzahl der Bytes an, die im Speicher zurückgelegt werden müssen, um den nächsten Wert einer Achse eines Arrays zu erreichen.
Unser 3D-Array
arr
sieht nun so aus (mit beschrifteten Achsen):Dieses Array wird in einem zusammenhängenden Speicherblock gespeichert . im wesentlichen ist es eindimensional. Um es als 3D-Objekt zu interpretieren, muss NumPy über eine bestimmte konstante Anzahl von Bytes springen, um sich entlang einer der drei Achsen zu bewegen:
Da jede Ganzzahl 8 Byte Speicher belegt (wir verwenden den Int64-Typ), beträgt der Schrittwert für jede Dimension das 8-fache der Anzahl der Werte, die wir überspringen müssen. Um sich beispielsweise entlang der Achse 1 zu bewegen, werden vier Werte (32 Bytes) übersprungen, und um sich entlang der Achse 0 zu bewegen, müssen acht Werte (64 Bytes) übersprungen werden.
Wenn wir schreiben
arr.transpose(1, 0, 2)
, tauschen wir die Achsen 0 und 1 aus. Das transponierte Array sieht folgendermaßen aus:Alles, was NumPy tun muss, ist, die Schrittinformationen für Achse 0 und Achse 1 auszutauschen (Achse 2 bleibt unverändert). Jetzt müssen wir weiter springen, um uns entlang der Achse 1 als entlang der Achse 0 zu bewegen:
Dieses Grundkonzept funktioniert für jede Permutation der Achsen eines Arrays. Der eigentliche Code für die Transponierung ist in C geschrieben und befindet sich hier .
quelle
Wie in der Dokumentation erläutert :
Sie können also einen optionalen Parameter übergeben
axes
, der die neue Reihenfolge der Dimensionen definiert.Beispiel: Transponieren der ersten beiden Dimensionen eines RGB-VGA-Pixel-Arrays:
>>> x = np.ones((480, 640, 3)) >>> np.transpose(x, (1, 0, 2)).shape (640, 480, 3)
quelle
In C-Notation wäre Ihr Array:
int arr[2][2][4]
Dies ist ein 3D-Array mit 2 2D-Arrays. Jedes dieser 2D-Arrays hat 2 1D-Arrays, jedes dieser 1D-Arrays hat 4 Elemente.
Sie haben also drei Dimensionen. Die Achsen sind 0, 1, 2 mit den Größen 2, 2, 4. Genau so behandelt numpy die Achsen eines N-dimensionalen Arrays.
So
arr.transpose((1, 0, 2))
würde die Achse 1 und legen Sie sie in Position 0, 0 Achse und legen Sie sie in Position 1 und Achse 2 und lassen Sie ihn in Position 2. Sie effektiv die Achsen Permutation:0 -\/-> 0 1 -/\-> 1 2 ----> 2
Mit anderen Worten
1 -> 0, 0 -> 1, 2 -> 2
. Die Zielachsen sind immer in Ordnung. Sie müssen also nur die Quellachsen angeben. Lesen Sie das Tupel in dieser Reihenfolge ab :(1, 0, 2)
.In diesem Fall sind Ihre neuen Array-Dimensionen wieder da
[2][2][4]
, nur weil die Achsen 0 und 1 dieselbe Größe hatten (2).Interessanter ist eine Transponierung, mit
(2, 1, 0)
der Sie eine Reihe von erhalten[4][2][2]
.0 -\ /--> 0 1 --X---> 1 2 -/ \--> 2
Mit anderen Worten
2 -> 0, 1 -> 1, 0 -> 2
. Lesen Sie das Tupel in dieser Reihenfolge ab :(2, 1, 0)
.>>> arr.transpose((2,1,0)) array([[[ 0, 8], [ 4, 12]], [[ 1, 9], [ 5, 13]], [[ 2, 10], [ 6, 14]], [[ 3, 11], [ 7, 15]]])
Sie endeten mit einem
int[4][2][2]
.Sie werden wahrscheinlich besser verstehen, wenn alle Dimensionen unterschiedlich groß sind, sodass Sie sehen können, wohin die einzelnen Achsen führen.
Warum ist das erste innere Element
[0, 8]
? Denn wenn Sie Ihr 3D-Array als zwei Blatt Papier visualisieren0
und8
aneinandergereiht sind, eins auf einem Papier und eins auf dem anderen Papier, beide oben links. Durch das Transponieren(2, 1, 0)
möchten Sie, dass die Richtung von Papier zu Papier jetzt von links nach rechts entlang des Papiers und die Richtung von links nach rechts von Papier zu Papier verläuft. Sie hatten 4 Elemente von links nach rechts, jetzt haben Sie stattdessen vier Zettel. Und Sie hatten 2 Papiere, also haben Sie jetzt 2 Elemente, die von links nach rechts gehen.Entschuldigung für die schreckliche ASCII-Kunst.
¯\_(ツ)_/¯
quelle
transpose()
keine mathematische Permutation ist oder so? Es ist buchstäblich nur eine Anweisung, die besagt: "Lass die Achsen jetzt in diesen Positionen sein"? Zum Beispiel, weil.transpose(p, q, r, s)
Sie sagen "Achsep
als 0.,q
als 1.,r
als 2. unds
als 3. setzen"? Oder anders gesehenb = a.transpose(axes)
heißtb.shape == tuple(a.shape[i] for i in axes)
?Es scheint, dass die Frage und das Beispiel aus dem Buch Python for Data Analysis von Wes McKinney stammen. Diese Funktion von
transpose
wird in Kapitel 4.1 erwähnt. Transponieren von Arrays und Vertauschen von Achsen .Hier bedeutet "permutieren" "neu anordnen", also die Reihenfolge der Achsen neu anordnen.
Die Zahlen in
.transpose(1, 0, 2)
bestimmen, wie die Reihenfolge der Achsen im Vergleich zum Original geändert wird. Mit verwenden.transpose(1, 0, 2)
wir "Ändern Sie die 1. Axt mit der 2 .." Wenn wir verwenden.transpose(0, 1, 2)
, bleibt das Array gleich, da nichts geändert werden muss. Dies ist die Standardreihenfolge.Das Beispiel im Buch mit einem
(2, 2, 4)
Array mit einer Größe ist nicht sehr klar, da die 1. und 2. Achse dieselbe Größe haben. Das Endergebnis scheint sich also nur durch die Neuordnung der Zeilenarr[0, 1]
und zu ändernarr[1, 0]
.Wenn wir ein anderes Beispiel mit einem dreidimensionalen Array versuchen, wobei jede Dimension eine andere Größe hat, wird der Umlagerungsteil klarer.
In [2]: x = np.arange(24).reshape(2, 3, 4) In [3]: x Out[3]: array([[[ 0, 1, 2, 3], [ 4, 5, 6, 7], [ 8, 9, 10, 11]], [[12, 13, 14, 15], [16, 17, 18, 19], [20, 21, 22, 23]]]) In [4]: x.transpose(1, 0, 2) Out[4]: array([[[ 0, 1, 2, 3], [12, 13, 14, 15]], [[ 4, 5, 6, 7], [16, 17, 18, 19]], [[ 8, 9, 10, 11], [20, 21, 22, 23]]])
Hier sind die ursprünglichen Arraygrößen
(2, 3, 4)
. Wir haben den 1. und 2. geändert, damit er(3, 2, 4)
größer wird. Wenn wir genauer hinschauen, um zu sehen, wie die Umlagerung genau passiert ist; Zahlenfelder scheinen sich in einem bestimmten Muster geändert zu haben. Unter Verwendung der Papieranalogie von @ RobertB hätten wir jetzt ein Array der Größe 3x2x4 , wenn wir die 2 Zahlenblöcke nehmen und jedes auf Blätter schreiben und dann eine Zeile von jedem Blatt nehmen würden, um eine Dimension des Arrays zu konstruieren Zählen von der äußersten bis zur innersten Schicht.[ 0, 1, 2, 3] \ [12, 13, 14, 15]
[ 4, 5, 6, 7] \ [16, 17, 18, 19]
[ 8, 9, 10, 11] \ [20, 21, 22, 23]
Es könnte eine gute Idee sein, mit Arrays unterschiedlicher Größe zu spielen und verschiedene Achsen zu ändern, um eine bessere Vorstellung davon zu erhalten, wie es funktioniert.
quelle
Um a.transpose () zusammenzufassen [i, j, k] = a [k, j, i]
a = np.array( range(24), int).reshape((2,3,4)) a.shape gives (2,3,4) a.transpose().shape gives (4,3,2) shape tuple is reversed.
Wenn ein Tupelparameter übergeben wird, werden die Achsen entsprechend dem Tupel permutiert. Zum Beispiel
a = np.array (Bereich (24), int) .form ((2,3,4))
a [i, j, k] ist gleich a.transponieren ((2,0,1)) [k, i, j]
Achse 0 belegt den 2. Platz
Achse 1 belegt den 3. Platz
Achse 2 Geschichten 1. Platz
Natürlich müssen wir darauf achten, dass die Werte im Tupelparameter, die zur Transponierung übergeben werden, eindeutig und im Bereich (Anzahl der Achsen) sind.
quelle