Numpy Arrays: Konkatenieren, Reduzieren und Addieren von Dimensionen


Reduzieren und Reshape von Arrays

Stretching

Es gibt zwei Methoden um ein Multidimensionales Array zu reduzieren:

flatten

flatten ist eine ndarray Methode mit einem optionalen Parameter "order". "order" kann die Werte "C", "F" und "A" erhalten. Der Default-Wert von "order" ist "C".
"C" steht dafür, dass im C-Stil in der Zeilen-Haupt-Ordnung geglättet wird., d.h. der am weitesten rechts liegende Index "ändert sich am schnellsten". In anderen Worten: der Zeilenindex variiert in der Zeilen-Haupt-Ordnung am langsamsten und am Spaltenindex am schnellsten, so dass a[0, 1] auf a[0, 0] folgt.
"F" steht für "Fortran Spalten-Haupt-Orndung".
"A" steht für den Erhalt der "C/Fortran-Anordnung".

import numpy as np
A = np.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]]])
Flattened_X = A.flatten()
print(Flattened_X)
print(A.flatten(order="C"))
print(A.flatten(order="F"))
print(A.flatten(order="A"))
[ 0  1  2  3  4  5  6  7  8  9 10 11 12 13 14 15 16 17 18 19 20 21 22 23]
[ 0  1  2  3  4  5  6  7  8  9 10 11 12 13 14 15 16 17 18 19 20 21 22 23]
[ 0  8 16  2 10 18  4 12 20  6 14 22  1  9 17  3 11 19  5 13 21  7 15 23]
[ 0  1  2  3  4  5  6  7  8  9 10 11 12 13 14 15 16 17 18 19 20 21 22 23]

ravel

Die Reihenfolge der Elemente, die durch ravel() zurückgeliefert wird, ist im "C-Stil".

ravel(a, order='C')

ravel liefert ein abgeflachtes eindimensionales Array. Eine Kopie wird nur bei Notwendigkeit erstellt.

Der optionale Parameter "order" kann die Werte "C", "F", "A" oder "K" annehmen.

"C": C-Stil Reihenfolge, wobei sich der letzte Achsenindex am schnellsten ändert, zurück zum ersten Achsenindex, der sich am langsamten ändert. "C" ist der Default-Wert.

"F": Fortran-Stil Indexreihenfolge, wobei sich der erste Index am schnellsten ändert und der letzte Index am langsamsten.

"A": Fortran-Stil Indexreihenfolge wenn das Array 'a' im Speicher als Fortran vorliegt, andernfalls wird die C-Stil Reihenfolge verwendet.

"K": Die Elemente werden so gelesen, wie sie im Speicher vorkommen, ausser für Daten-Umkehrung wenn die Schrittweiten negativ sind.

print(A.ravel())
print(A.ravel(order="A"))
print(A.ravel(order="F"))
print(A.ravel(order="A"))
print(A.ravel(order="K"))
[ 0  1  2  3  4  5  6  7  8  9 10 11 12 13 14 15 16 17 18 19 20 21 22 23]
[ 0  1  2  3  4  5  6  7  8  9 10 11 12 13 14 15 16 17 18 19 20 21 22 23]
[ 0  8 16  2 10 18  4 12 20  6 14 22  1  9 17  3 11 19  5 13 21  7 15 23]
[ 0  1  2  3  4  5  6  7  8  9 10 11 12 13 14 15 16 17 18 19 20 21 22 23]
[ 0  1  2  3  4  5  6  7  8  9 10 11 12 13 14 15 16 17 18 19 20 21 22 23]

reshape

Die reshape-Methode gibt einem Array eine neue Shape, ohne die darin enthaltenen Daten zu ändern. D.h. die Methode liefert ein neues Array zurück mit einer neuen Shape.

reshape(a, newshape, order='C')

Parameter Bedeutung
a array_like, Array, dass geändert werden soll.
newshape Integer-Wert oder Integer-Tupel
order 'C', 'F', 'A', wie in flatten() oder ravel()
X = np.array(range(24))
Y = X.reshape((3,4,2))
Y
Wir können die folgende Ausgabe erwarten, wenn wir den obigen Python-Code ausführen:
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]]])


Arrays konkatenieren/zusammenführen

Im folgenden Beispiel konkatenieren wir 3 eindimensionale Arrays zu einem. Die Elemente des zweiten Arrays werden an das erste Array angefügt. Anschliessend werden die Elemente des dritten Arrays ebenfalls angefügt.

x = np.array([11,22])
y = np.array([18,7,6])
z = np.array([1,3,5])
c = np.concatenate((x,y,z))
print(c)
[11 22 18  7  6  1  3  5]

Wenn wir multidimensionale Arrays zusammenführen, müssen wir auf die Achsen achten. Die Arrays müssen die gleiche Shape haben um mit concatenate() zusammenzuführen. Bei multidimensionalen Arrays können wir diese entsprechend anordnen. Der Default-Wert ist axis = 0:

x = np.array(range(24))
x = x.reshape((3,4,2))
y = np.array(range(100,124))
y = y.reshape((3,4,2))
z = np.concatenate((x,y))
print(z)
[[[  0   1]
  [  2   3]
  [  4   5]
  [  6   7]]
 [[  8   9]
  [ 10  11]
  [ 12  13]
  [ 14  15]]
 [[ 16  17]
  [ 18  19]
  [ 20  21]
  [ 22  23]]
 [[100 101]
  [102 103]
  [104 105]
  [106 107]]
 [[108 109]
  [110 111]
  [112 113]
  [114 115]]
 [[116 117]
  [118 119]
  [120 121]
  [122 123]]]

Wir führen die Zusammenführung nun mit axis = 1 durch:

z = np.concatenate((x,y),axis = 1)
print(z)
[[[  0   1]
  [  2   3]
  [  4   5]
  [  6   7]
  [100 101]
  [102 103]
  [104 105]
  [106 107]]
 [[  8   9]
  [ 10  11]
  [ 12  13]
  [ 14  15]
  [108 109]
  [110 111]
  [112 113]
  [114 115]]
 [[ 16  17]
  [ 18  19]
  [ 20  21]
  [ 22  23]
  [116 117]
  [118 119]
  [120 121]
  [122 123]]]


Weitere Dimensionen hinzufügen

Weitere Dimensionen können zu einem Array mit Hilfe von Slicing und np.newaxis hinzugefügt werden. Wir demonstrieren die Technik im folgenden Beispiel:

x = np.array([2,5,18,14,4])
y = x[:, np.newaxis]
print(y)
[[ 2]
 [ 5]
 [18]
 [14]
 [ 4]]



Vektoren stapeln

A = np.array([3, 4, 5])
B = np.array([1,9,0])
print(np.row_stack((A, B)))
print(np.column_stack((A, B)))
np.shape(A)
[[3 4 5]
 [1 9 0]]
[[3 1]
 [4 9]
 [5 0]]
Wir können die folgende Ausgabe erwarten, wenn wir den obigen Python-Code ausführen:
(3,)
A = np.array([[3, 4, 5],
              [1, 9, 0],
              [4, 6, 8]])
np.column_stack((A, A, A))
Der obige Code liefert folgendes Ergebnis:
array([[3, 4, 5, 3, 4, 5, 3, 4, 5],
       [1, 9, 0, 1, 9, 0, 1, 9, 0],
       [4, 6, 8, 4, 6, 8, 4, 6, 8]])
np.column_stack((A[0], A[0], A[0]))
Wir können die folgende Ausgabe erwarten, wenn wir den obigen Python-Code ausführen:
array([[3, 3, 3],
       [4, 4, 4],
       [5, 5, 5]])
np.dstack((A, A, A))
Der obige Python-Code liefert folgendes Ergebnis:
array([[[3, 3, 3],
        [4, 4, 4],
        [5, 5, 5]],
       [[1, 1, 1],
        [9, 9, 9],
        [0, 0, 0]],
       [[4, 4, 4],
        [6, 6, 6],
        [8, 8, 8]]])



Muster wiederholen, Die "tile" Methode

Manchmal ist es nötig eine Matrix zu erstellen (mit einer anderen Shape oder Dimension), die den Inhalt einer existierenden Matrix mehrfach enthält. Beispiel: Sie möchten Sie das eindimensionale Array array([ 3.4]) in das Array array([ 3.4, 3.4, 3.4, 3.4, 3.4]) wandeln.

Weiteres Beispiel: Sie möchten ein zweidimensionales Array, wie np.array([ [1, 2], [3, 4]]), als Baustein benutzen um ein Array mit der Shape (6, 8) zu erstellen:

array([[1, 2, 1, 2, 1, 2, 1, 2],
       [3, 4, 3, 4, 3, 4, 3, 4],
       [1, 2, 1, 2, 1, 2, 1, 2],
       [3, 4, 3, 4, 3, 4, 3, 4],
       [1, 2, 1, 2, 1, 2, 1, 2],
       [3, 4, 3, 4, 3, 4, 3, 4]])

Die Konstruktions-Idee ist im folgenden Diagramm nochmal dargestellt:


Illustrating the way of working of the tile method

Wenn Sie nun an das verfliesen (engl. tiling) eines Bades denken, so sind Sie auf dem richtigen Weg: Die Funktion die Numpy hier zur Verfügung stellt, wird "tile" genannt.

Die formale Syntax von "tile" sieht wie folgt aus:

tile(A, reps)

Eine Array wird durch die Wiederholung von "A" generiert. Die Anzahl der Wiederholungen wird durch "reps" angegeben.

"reps" ist i.d.R. ein Tupel (oder eine Liste), welche die Anzahl der Wiederholungen entlang der Achse/Richtung definiert.

Wenn "reps" bspw. mit (3,4) gesetzt wird, wird "A" 3x entlang der Zeilen und 4x entlang der Spalten wiederholt. Im folgenden Beispiel demonstrieren wir dieses Verhalten:

import numpy as np
x = np.array([ [1, 2], [3, 4]])
np.tile(x, (3,4))
Wir können die folgende Ausgabe erwarten, wenn wir den obigen Python-Code ausführen:
array([[1, 2, 1, 2, 1, 2, 1, 2],
       [3, 4, 3, 4, 3, 4, 3, 4],
       [1, 2, 1, 2, 1, 2, 1, 2],
       [3, 4, 3, 4, 3, 4, 3, 4],
       [1, 2, 1, 2, 1, 2, 1, 2],
       [3, 4, 3, 4, 3, 4, 3, 4]])
import numpy as np
x = np.array([ 3.4])
y = np.tile(x, (5,)) 
print(y)
[ 3.4  3.4  3.4  3.4  3.4]

Im vorigen tile-Beispiel hätten wir ebenso y = np.tile(x, 5) schreiben können.

Wenn wir "reps" in Tupel- oder List-Form schreiben, oder reps = 5 als Ersatz für reps = (5,) in Erwägung ziehen, so ist folgendes wahr:

Wenn "reps" die Länge n hat, so wird die Dimension des resultierenden Arrays maximal n und A.ndim sein.

Wenn A.ndim < n ist, so wird "A" durch voranstellen neuer Achsen auf die n-Dimension befördert. Bspw. wird ein Array mit der Shape (5,) auf (1,5) bei einer 2-D-Replikation befördert, oder auf die Shape (1, 1, 5) bei einer 3-D-Replikation. Sollte das nicht dem gewünschten Verhalten entsprechen, so ist "A" vor dem Aufruf der tile-Funktion auf die gewünschte Shape anzupassen.

Wenn A.ndim > d ist, so wird "reps" auf A.ndim angepasst, indem 1's vorangestellt werden. Bspw. wird ein Array "A" mit der Shape (2, 3, 4, 5) und reps = (2, 2) als (1, 1, 2, 2) behandelt.

Weitere Beispiele:

import numpy as np
x = np.array([[1, 2], [3, 4]])
print(np.tile(x, 2))
[[1 2 1 2]
 [3 4 3 4]]
import numpy as np
x = np.array([[1, 2], [3, 4]])
print(np.tile(x, (2, 1)))
[[1 2]
 [3 4]
 [1 2]
 [3 4]]
import numpy as np
x = np.array([[1, 2], [3, 4]])
print(np.tile(x, (2, 2)))
[[1 2 1 2]
 [3 4 3 4]
 [1 2 1 2]
 [3 4 3 4]]