So ändern Sie NumPy-Arrays in Python

In diesem Tutorial erfahren Sie, wie Sie mit der Funktion NumPy reshape() die Form von NumPy-Arrays verändern können, ohne die ursprünglichen Daten zu manipulieren.

Bei der Arbeit mit NumPy-Arrays kann es häufig vorkommen, dass Sie ein bestehendes Array in ein Array mit unterschiedlichen Dimensionen transformieren müssen. Dies ist besonders nützlich bei der mehrstufigen Verarbeitung von Daten.

Die Funktion NumPy reshape() macht dies einfach. In den folgenden Minuten werden Sie die Syntax der Funktion reshape() kennenlernen und erfahren, wie man Arrays in andere Dimensionen umwandelt.

Was bedeutet Umformen von NumPy-Arrays?

Wenn Sie mit NumPy-Arrays arbeiten, beginnen Sie oft mit der Erstellung eines eindimensionalen Arrays. Anschließend formen Sie dieses Array in die gewünschten Dimensionen um.

Dies ist besonders hilfreich, wenn die Dimensionen des neuen Arrays zu Beginn nicht bekannt sind oder erst während der Programmausführung festgelegt werden. Es kann auch vorkommen, dass ein bestimmter Verarbeitungsschritt eine spezifische Eingabeform benötigt.

Hier kommt die Funktion zum Umformen ins Spiel.

Betrachten Sie zum Beispiel das folgende Szenario: Wir haben einen Vektor – ein eindimensionales Array mit 6 Elementen. Diesen Vektor können wir in Arrays der Form 2×3, 3×2, 6×1 und so weiter umwandeln.

▶️ Um den Beispielen in diesem Tutorial folgen zu können, sollten Sie Python und NumPy installiert haben. Falls NumPy noch nicht installiert ist, finden Sie in unserer Installationsanleitung Hilfe zur NumPy-Installation.

Importieren Sie nun NumPy unter dem Alias np mit folgendem Befehl: import numpy as np.

Lassen Sie uns im nächsten Abschnitt die Syntax kennenlernen.

Syntax von NumPy reshape()

Hier ist die Syntax für die Verwendung von NumPy reshape():

np.reshape(arr, newshape, order="C"|'F'|'A')
  • arr ist ein beliebiges gültiges NumPy-Array-Objekt. Dies ist das Array, das umgeformt werden soll.
  • newshape definiert die Form des neuen Arrays. Dies kann entweder eine Ganzzahl oder ein Tupel sein.
  • Wenn newshape eine Ganzzahl ist, ist das resultierende Array eindimensional.
  • order bestimmt die Reihenfolge, in der die Elemente des umzuformenden Arrays gelesen werden sollen.
  • Der Standardwert ist 'C', was bedeutet, dass die Elemente des ursprünglichen Arrays in C-ähnlicher Indizierungsreihenfolge (beginnend mit 0) gelesen werden.
  • 'F' steht für Fortran-ähnliche Indizierung (beginnend mit 1). 'A' liest die Elemente entweder in C-ähnlicher oder Fortran-ähnlicher Reihenfolge, je nach Speicherlayout des Arrays arr.

Was gibt np.reshape() zurück?

Die Funktion gibt, wenn möglich, eine umgeformte *Ansicht* des ursprünglichen Arrays zurück. Andernfalls wird eine Kopie des Arrays zurückgegeben.

Oben wurde erwähnt, dass NumPy reshape() wenn möglich eine *Ansicht* zurückgeben wird. Andernfalls wird eine Kopie erstellt. Lassen Sie uns nun den Unterschied zwischen *Ansicht* und *Kopie* erläutern.

Ansicht vs. Kopie von NumPy-Arrays

Wie der Name schon sagt, ist eine *Kopie* eine exakte Duplizierung des ursprünglichen Arrays. Änderungen an der Kopie haben keine Auswirkungen auf das ursprüngliche Array.

Eine *Ansicht* hingegen ist lediglich eine umgeformte Darstellung des ursprünglichen Arrays. Das bedeutet, dass jede Änderung, die an der *Ansicht* vorgenommen wird, auch das ursprüngliche Array verändert und umgekehrt.

Verwendung von NumPy reshape() zur Umformung von 1D-Arrays in 2D-Arrays

#1. Beginnen wir mit der Erstellung eines Beispielarrays mit np.arange().

Wir benötigen ein Array mit 12 Zahlen, von 1 bis 12, das wir arr1 nennen. Da die Funktion NumPy arange() den Endpunkt standardmäßig ausschließt, setzen wir den Stoppwert auf 13.

Verwenden wir nun die obige Syntax, um arr1 mit 12 Elementen in ein 2D-Array der Form (4,3) umzuformen. Nennen wir dies arr2 mit 4 Zeilen und 3 Spalten.

import numpy as np

arr1 = np.arange(1,13)
print("Ursprüngliches Array, vor der Umformung:n")
print(arr1)

# Umformen des Arrays
arr2 = np.reshape(arr1,(4,3))
print("nUmgeformtes Array:")
print(arr2)

Werfen wir einen Blick auf die ursprünglichen und umgeformten Arrays.

Ursprüngliches Array, vor der Umformung:

[ 1  2  3  4  5  6  7  8  9 10 11 12]

Umgeformtes Array:
[[ 1  2  3]
 [ 4  5  6]
 [ 7  8  9]
 [10 11 12]]

Anstatt das Array als Argument an np.reshape() zu übergeben, können Sie auch die Methode .reshape() für das ursprüngliche Array aufrufen.

Wenn Sie dir(arr1) ausführen, erhalten Sie eine Liste aller möglichen Methoden und Attribute, die Sie für das Array-Objekt arr1 verwenden können.

dir(arr1)

# Ausgabe
[
...
...
'reshape'
...
..
]

In der obigen Codezelle können Sie sehen, dass .reshape() eine gültige Methode ist, die für das bestehende NumPy-Array arr1 verwendet werden kann.

▶️ Sie können also auch die folgende, vereinfachte Syntax verwenden, um NumPy-Arrays umzuformen.

arr.reshape(d0,d1,...,dn)

# wobei:

# d0, d1,..,dn die Dimensionen des umgeformten Arrays sind

# d0 * d1 * ...* dn = N, die Anzahl der Elemente in arr

Für den Rest dieses Tutorials werden wir diese Syntax in unseren Beispielen verwenden.

#2. Versuchen wir, unseren 12-Elemente-Vektor in ein 12 x 1-Array umzuformen.

import numpy as np

arr1 = np.arange(1,13)
print("Ursprüngliches Array, vor der Umformung:n")
print(arr1)

# Umformen des Arrays
arr3 = arr1.reshape(12,1)
print("nUmgeformtes Array:")
print(arr3)

In der Ausgabe unten sehen Sie, dass das Array wie gewünscht umgeformt wurde.

Ursprüngliches Array, vor der Umformung:

[ 1  2  3  4  5  6  7  8  9 10 11 12]

Umgeformtes Array:
[[ 1]
 [ 2]
 [ 3]
 [ 4]
 [ 5]
 [ 6]
 [ 7]
 [ 8]
 [ 9]
 [10]
 [11]
 [12]]

❔ Wie überprüfen wir also, ob wir eine Kopie oder eine Ansicht erhalten haben?

Um dies zu überprüfen, können Sie das Attribut base für das zurückgegebene Array aufrufen.

  • Wenn das Array eine *Kopie* ist, ist das Attribut base None.
  • Wenn das Array eine *Ansicht* ist, ist das Attribut base das ursprüngliche Array.

Lassen Sie uns dies kurz überprüfen.

arr3.base
# Ausgabe
array([ 1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12])

Wie Sie sehen, gibt das Attribut base von arr3 das ursprüngliche Array zurück. Das bedeutet, dass wir eine *Ansicht* des ursprünglichen Arrays erhalten haben.

#3. Versuchen wir nun, den Vektor in ein anderes gültiges 2 x 6-Array umzuformen.

import numpy as np

arr1 = np.arange(1,13)
print("Ursprüngliches Array, vor der Umformung:n")
print(arr1)

# Umformen des Arrays
arr4 = arr1.reshape(2,6)
print("nUmgeformtes Array:")
print(arr4)

Und hier ist die Ausgabe:

Ursprüngliches Array, vor der Umformung:

[ 1  2  3  4  5  6  7  8  9 10 11 12]

Umgeformtes Array:
[[ 1  2  3  4  5  6]
 [ 7  8  9 10 11 12]]

Lassen Sie uns im nächsten Abschnitt arr1 in ein 3D-Array umformen.

Verwendung von NumPy reshape() zur Umformung von 1D-Arrays in 3D-Arrays

Um arr1 in ein 3D-Array umzuformen, setzen wir die gewünschten Dimensionen auf (1, 4, 3).

import numpy as np

arr1 = np.arange(1,13)
print("Ursprüngliches Array, vor der Umformung:n")
print(arr1)

# Umformen des Arrays
arr3D = arr1.reshape(1,4,3)
print("nUmgeformtes Array:")
print(arr3D)

Wir haben jetzt ein 3D-Array mit denselben 12 Elementen wie das ursprüngliche Array arr1 erstellt.

Ursprüngliches Array, vor der Umformung:

[ 1  2  3  4  5  6  7  8  9 10 11 12]

Umgeformtes Array:
[[[ 1  2  3]
  [ 4  5  6]
  [ 7  8  9]
  [10 11 12]]]

So beheben Sie Wertfehler während der Umformung

Denken Sie an die Syntax: Die Umformung ist nur dann gültig, wenn das Produkt der Dimensionen gleich der Anzahl der Elemente im Array ist.

import numpy as np

arr1 = np.arange(1,13)
print("Ursprüngliches Array, vor der Umformung:n")
print(arr1)

# Umformen des Arrays
arr2D = arr1.reshape(4,4)
print("nUmgeformtes Array:")
print(arr2D)

Hier versuchen wir, ein 12-Elemente-Array in ein 4×4-Array mit 16 Elementen umzuformen. Der Interpreter gibt einen Wertfehler aus, wie unten gezeigt.

Ursprüngliches Array, vor der Umformung:

[ 1  2  3  4  5  6  7  8  9 10 11 12]
-----------------------------------------------------------
ValueError                                
Traceback (most recent call last)
<ipython-input-11-63552bcc8c37> in <module>()
      6 
      7 # Umformen des Arrays
----> 8 arr2 = arr1.reshape(4,4)
      9 print("nUmgeformtes Array:")
     10 print(arr2)

ValueError: cannot reshape array of size 12 into shape (4,4)

Um solche Fehler zu vermeiden, können Sie -1 verwenden, um die Form für eine der Dimensionen automatisch abzuleiten – basierend auf der Gesamtzahl der Elemente.

Wenn Sie beispielsweise n – 1 Dimensionen im Voraus kennen, können Sie mit -1 die n-te Dimension im umgeformten Array ableiten.

Angenommen, Sie haben ein Array mit 24 Elementen und möchten es in ein 3D-Array umformen. Nehmen wir an, Sie benötigen 3 Zeilen und 4 Spalten. Sie können den Wert -1 entlang der dritten Dimension übergeben.

import numpy as np

arr1 = np.arange(1,25)
print("Ursprüngliches Array, vor der Umformung:n")
print(arr1)

# Umformen des Arrays
arr_res = arr1.reshape(4,3,-1)
print("nUmgeformtes Array:")
print(arr_res)
print(f"Form von arr_res:{arr_res.shape}")

Wenn Sie die Form des arr_res-Arrays untersuchen, können Sie sehen, dass das umgeformte Array entlang der dritten Dimension eine Form von 2 hat.

Ursprüngliches Array, vor der Umformung:

[ 1  2  3  4  5  6  7  8  9 10 11 12 
13 14 15 16 17 18 19 20 21 22 23 24]

Umgeformtes Array:
[[[ 1  2]
  [ 3  4]
  [ 5  6]]

 [[ 7  8]
  [ 9 10]
  [11 12]]

 [[13 14]
  [15 16]
  [17 18]]

 [[19 20]
  [21 22]
  [23 24]]]
Form von arr_res:(4, 3, 2)

Dies ist besonders hilfreich, wenn Sie ein Array vereinfachen möchten. Das erfahren Sie im nächsten Abschnitt.

Verwenden von NumPy reshape() zum Reduzieren eines Arrays

Es gibt Situationen, in denen Sie von mehrdimensionalen Arrays zu einem reduzierten Array zurückkehren müssen. Nehmen wir an, Sie möchten ein Bild in einen langen Pixelvektor umwandeln.

Lassen Sie uns ein einfaches Beispiel mit folgenden Schritten programmieren:

  • Generieren Sie ein 3 x 3 Graustufen-Bildarray, img_arr – mit Pixeln im Bereich von 0 bis 255.
  • Als Nächstes reduzieren Sie dieses img_arr und geben das reduzierte Array flat_arr aus.
  • Geben Sie zur Überprüfung auch die Formen von img_arr und flat_arr aus.
img_arr = np.random.randint(0, 255, (3,3))
print(img_arr)
print(f"Form von img_arr: {img_arr.shape}")
flat_arr = img_arr.reshape(-1)
print(flat_arr)
print(f"Form von flat_arr: {flat_arr.shape}")

Hier ist die Ausgabe.

[[195 145  77]
 [ 63 193 223]
 [215  43  36]]
Form von img_arr: (3, 3)

[195 145  77  63 193 223 215  43  36]
Form von flat_arr: (9,)

In der obigen Codezelle sehen Sie, dass flat_arr ein 1D-Vektor von Pixelwerten mit 9 Elementen ist.

Zusammenfassung 👩‍🏫

Es ist an der Zeit, das Gelernte kurz zusammenzufassen.

  • Verwenden Sie np.reshape(arr, newshape), um arr in die Form umzuformen, die durch newshape definiert wird. newshape ist ein Tupel, das die Dimensionen des umgeformten Arrays angibt.
  • Alternativ können Sie arr.reshape(d0, d1, …, dn) verwenden, um arr in die Form d0 x d1 x … x dn umzuformen.
  • Überprüfen Sie, ob d0 * d1 * …* dn = N gilt, wobei N die Anzahl der Elemente im ursprünglichen Array ist, um Wertfehler während der Umformung zu vermeiden.
  • Verwenden Sie -1 für höchstens eine Dimension in der neuen Form, wenn Sie möchten, dass die Dimension automatisch abgeleitet wird.
  • Schließlich können Sie arr.reshape(-1) verwenden, um das Array zu reduzieren.

Nachdem Sie nun wissen, wie NumPy reshape() verwendet wird, lesen Sie, wie die NumPy-Funktion linspace() funktioniert.

Sie können die Codebeispiele in einem Jupyter-Notebook ausprobieren, falls gewünscht. Wenn Sie nach anderen Entwicklungsumgebungen suchen, sehen Sie sich unseren Leitfaden zu Jupyter-Alternativen an.