Skip to content
Themen
NumPy
NumPy Reshape: So ändern Sie Array-Formen in Python

NumPy Reshape: So ändern Sie Array-Formen in Python

Updated on

Sie haben eine flache Liste mit 10.000 Pixelwerten und ein neuronales Netzwerk, das eine 100x100-Bildmatrix erwartet. Oder vielleicht wirft scikit-learn einen Fehler, weil Ihr Feature-Array eindimensional ist, obwohl es ein Spaltenvektor sein müsste. Das sind keine Randfälle -- das sind tägliche Hindernisse für jeden, der mit numerischen Daten in Python arbeitet. Die Funktion, die diese Probleme löst, ist numpy.reshape(), und sie richtig zu verstehen spart Stunden beim Debugging.

📚

Was macht numpy reshape?

numpy.reshape() ändert die Form eines Arrays, ohne seine Daten zu verändern. Es nimmt die gleichen Elemente und ordnet sie in neue Dimensionen um. Ein 1D-Array mit 12 Elementen kann zu einer 3x4-Matrix, einer 2x6-Matrix, einer 4x3-Matrix oder sogar zu einem dreidimensionalen 2x2x3-Array werden. Die einzige Regel ist, dass die Gesamtzahl der Elemente gleich bleiben muss.

import numpy as np
 
a = np.array([1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12])
print(a.shape)
# (12,)
 
b = a.reshape(3, 4)
print(b)
# [[ 1  2  3  4]
#  [ 5  6  7  8]
#  [ 9 10 11 12]]
 
print(b.shape)
# (3, 4)

Das ursprüngliche Array a existiert weiterhin mit seiner ursprünglichen Form. Das umgeformte Array b ist eine neue Ansicht derselben Daten (mehr zu Ansichten vs. Kopien später).

Grundlegende Syntax und Parameter

Es gibt zwei Möglichkeiten, ein Array in NumPy umzuformen:

# Methode 1: Als Funktion
np.reshape(array, newshape, order='C')
 
# Methode 2: Als Array-Methode
array.reshape(newshape, order='C')
ParameterTypBeschreibung
arrayndarrayDas umzuformende Array (nur für die Funktionsform np.reshape())
newshapeint oder Tupel von intsDie Zielform. Eine Dimension kann -1 sein, die automatisch berechnet wird.
order'C', 'F' oder 'A'Lese-/Schreibreihenfolge der Elemente. 'C' = zeilenweise (Standard), 'F' = spaltenweise, 'A' = Fortran-Reihenfolge wenn das Array Fortran-zusammenhängend ist, sonst C-Reihenfolge.

Beide Formen liefern identische Ergebnisse. Die Methodenform (array.reshape()) ist gebräuchlicher, da sie im Code natürlicher lesbar ist.

1D- zu 2D-Arrays umformen

Dies ist die häufigste Reshape-Operation. Man beginnt mit einem flachen Array und benötigt eine Matrix.

import numpy as np
 
# 1D-Array mit 8 Elementen
data = np.array([10, 20, 30, 40, 50, 60, 70, 80])
 
# Umformen zu 2 Zeilen, 4 Spalten
matrix_2x4 = data.reshape(2, 4)
print(matrix_2x4)
# [[10 20 30 40]
#  [50 60 70 80]]
 
# Umformen zu 4 Zeilen, 2 Spalten
matrix_4x2 = data.reshape(4, 2)
print(matrix_4x2)
# [[10 20]
#  [30 40]
#  [50 60]
#  [70 80]]
 
# Umformen zu einem Spaltenvektor (8 Zeilen, 1 Spalte)
column_vector = data.reshape(8, 1)
print(column_vector)
# [[10]
#  [20]
#  [30]
#  [40]
#  [50]
#  [60]
#  [70]
#  [80]]
 
print(column_vector.shape)
# (8, 1)

Die Spaltenvektor-Umformung (n, 1) ist besonders wichtig. Viele scikit-learn-Funktionen erfordern 2D-Eingaben, selbst für ein einzelnes Feature. Wenn Sie ein 1D-Array übergeben, erhalten Sie den Fehler Expected 2D array, got 1D array instead. Die Lösung ist .reshape(-1, 1).

2D zu 3D umformen (Für Machine Learning und Deep Learning)

Deep-Learning-Frameworks wie TensorFlow und PyTorch erfordern oft 3D- oder 4D-Eingabetensoren. Zum Beispiel benötigt ein Batch von Graustufenbildern die Form (batch_size, height, width), und ein Batch von Farbbildern benötigt (batch_size, height, width, channels).

import numpy as np
 
# 4 Graustufenbilder im Format 3x3, gespeichert als Zeilen in einem 2D-Array
images_2d = np.arange(36).reshape(4, 9)
print(images_2d.shape)
# (4, 9)
 
# Umformen zu (Batch, Höhe, Breite)
images_3d = images_2d.reshape(4, 3, 3)
print(images_3d.shape)
# (4, 3, 3)
 
print(images_3d[0])
# [[0 1 2]
#  [3 4 5]
#  [6 7 8]]

Für Farbbilder mit 3 Kanälen (RGB):

import numpy as np
 
# 2 Farbbilder, jeweils 4x4 mit 3 Kanälen, flach gespeichert
flat_data = np.arange(96)  # 2 * 4 * 4 * 3 = 96
 
images = flat_data.reshape(2, 4, 4, 3)
print(images.shape)
# (2, 4, 4, 3)

Der -1-Trick: Eine Dimension automatisch berechnen

Wenn Sie eine Dimension auf -1 setzen, berechnet NumPy sie automatisch basierend auf der Gesamtzahl der Elemente und den anderen angegebenen Dimensionen. Dies ist eine der nützlichsten Funktionen von reshape.

import numpy as np
 
arr = np.arange(12)
 
# "Gib mir 3 Zeilen, berechne die Spalten"
print(arr.reshape(3, -1))
# [[ 0  1  2  3]
#  [ 4  5  6  7]
#  [ 8  9 10 11]]
# Form: (3, 4) -- NumPy hat 4 Spalten berechnet
 
# "Gib mir 2 Spalten, berechne die Zeilen"
print(arr.reshape(-1, 2))
# [[ 0  1]
#  [ 2  3]
#  [ 4  5]
#  [ 6  7]
#  [ 8  9]
#  [10 11]]
# Form: (6, 2) -- NumPy hat 6 Zeilen berechnet
 
# Zu 1D abflachen
print(arr.reshape(-1))
# [ 0  1  2  3  4  5  6  7  8  9 10 11]
# Form: (12,)
 
# Spaltenvektor
print(arr.reshape(-1, 1).shape)
# (12, 1)

Sie können -1 nur für eine einzige Dimension verwenden. Die Verwendung für zwei oder mehr Dimensionen erzeugt einen Fehler, da die Berechnung mehrdeutig wird.

import numpy as np
 
arr = np.arange(12)
 
# Das SCHLÄGT FEHL:
# arr.reshape(-1, -1)
# ValueError: can only specify one unknown dimension

reshape() vs resize(): Wichtige Unterschiede

Beide Funktionen ändern Array-Formen, verhalten sich aber sehr unterschiedlich.

Eigenschaftreshape()resize()
Gibt zurückNeues Array (Ansicht oder Kopie)Ändert Array in-place (Methode) oder gibt neues Array zurück (Funktion)
Größe muss übereinstimmenJa -- Gesamtelemente müssen identisch seinNein -- füllt mit Nullen auf oder schneidet ab
Original-ArrayUnverändertGeändert (bei Verwendung von ndarray.resize())
SicherheitWirft Fehler bei GrößenunterschiedFüllt oder schneidet stillschweigend ab
Typische VerwendungDimensionen umordnenArray-Größe ändern
import numpy as np
 
arr = np.array([1, 2, 3, 4, 5, 6])
 
# reshape: muss gleiche Gesamtelemente behalten
reshaped = arr.reshape(2, 3)
print(reshaped)
# [[1 2 3]
#  [4 5 6]]
 
# np.resize (Funktionsform): füllt durch Wiederholung auf, wenn neue Größe größer ist
resized = np.resize(arr, (3, 3))
print(resized)
# [[1 2 3]
#  [4 5 6]
#  [1 2 3]]   <-- wiederholt von Anfang an
 
# np.resize: schneidet ab, wenn neue Größe kleiner ist
resized_small = np.resize(arr, (2, 2))
print(resized_small)
# [[1 2]
#  [3 4]]

Verwenden Sie reshape(), wenn Sie Dimensionen umordnen möchten, ohne Daten zu ändern. Verwenden Sie resize() nur, wenn Sie tatsächlich die Anzahl der Elemente ändern müssen.

Der Order-Parameter: C vs F vs A

Der order-Parameter steuert, wie Elemente aus dem ursprünglichen Array gelesen und in die neue Form eingefügt werden. Dies ist wichtig, wenn Sie mit Daten aus verschiedenen Programmiersprachen oder Speicherformaten arbeiten.

import numpy as np
 
arr = np.array([1, 2, 3, 4, 5, 6])
 
# C-Reihenfolge (zeilenweise): füllt Zeile für Zeile -- dies ist der Standard
c_order = arr.reshape(2, 3, order='C')
print("C-Reihenfolge:")
print(c_order)
# [[1 2 3]
#  [4 5 6]]
 
# F-Reihenfolge (spaltenweise): füllt Spalte für Spalte
f_order = arr.reshape(2, 3, order='F')
print("F-Reihenfolge:")
print(f_order)
# [[1 3 5]
#  [2 4 6]]
OrderNameFüllungAnwendungsfall
'C'C-Stil / ZeilenweiseZeile für Zeile (letzter Index ändert sich am schnellsten)Standard-Python/C/C++-Speicherlayout
'F'Fortran-Stil / SpaltenweiseSpalte für Spalte (erster Index ändert sich am schnellsten)MATLAB-, Fortran-, R-Daten
'A'AutomatischVerwendet F wenn Array Fortran-zusammenhängend ist, sonst CBestehendes Speicherlayout beibehalten

In den meisten Fällen werden Sie die Standard-'C'-Reihenfolge verwenden. Die 'F'-Reihenfolge benötigen Sie beim Laden von Daten, die aus MATLAB oder Fortran exportiert wurden, wo Matrizen spaltenweise gespeichert werden.

Ansichten vs. Kopien: Wann Reshape eine Ansicht zurückgibt

Ein kritisches Detail: reshape() gibt wenn möglich eine Ansicht des ursprünglichen Arrays zurück. Eine Ansicht teilt denselben zugrunde liegenden Speicher. Das Ändern der Ansicht ändert das ursprüngliche Array und umgekehrt.

import numpy as np
 
original = np.arange(6)
reshaped = original.reshape(2, 3)
 
# Die umgeformte Ansicht ändern
reshaped[0, 0] = 999
 
print(original)
# [999   1   2   3   4   5]   <-- Original hat sich auch geändert!

Wenn NumPy keine Ansicht erstellen kann (zum Beispiel wenn das Speicherlayout nicht mit der neuen Form kompatibel ist), gibt es stattdessen eine Kopie zurück. Sie können eine Kopie explizit erzwingen:

import numpy as np
 
original = np.arange(6)
reshaped_copy = original.reshape(2, 3).copy()
 
reshaped_copy[0, 0] = 999
print(original)
# [0 1 2 3 4 5]   <-- Original ist NICHT betroffen

Um zu prüfen, ob ein Reshape eine Ansicht oder eine Kopie zurückgegeben hat, untersuchen Sie das base-Attribut:

import numpy as np
 
arr = np.arange(6)
view = arr.reshape(2, 3)
copy = arr.reshape(2, 3).copy()
 
print(view.base is arr)   # True -- es ist eine Ansicht
print(copy.base is arr)   # False -- es ist eine Kopie

Häufige Fehler und wie man sie behebt

Fehler: "cannot reshape array of size X into shape Y"

Dies ist der häufigste Reshape-Fehler. Er tritt auf, wenn die Gesamtzahl der Elemente nicht zur Zielform passt.

import numpy as np
 
arr = np.arange(10)
 
# Das SCHLÄGT FEHL, weil 10 != 3 * 4 = 12
# arr.reshape(3, 4)
# ValueError: cannot reshape array of size 10 into shape (3,4)

Lösungen:

  1. Überprüfen Sie Ihre Berechnung. Stellen Sie sicher, dass das Produkt aller Zieldimensionen gleich arr.size ist.
import numpy as np
 
arr = np.arange(10)
print(arr.size)  # 10
 
# Gültige Formen für 10 Elemente: (2,5), (5,2), (1,10), (10,1), (10,)
print(arr.reshape(2, 5))
# [[0 1 2 3 4]
#  [5 6 7 8 9]]
  1. Füllen oder kürzen Sie das Array, wenn Sie wirklich eine Form benötigen, die nicht gleichmäßig teilbar ist.
import numpy as np
 
arr = np.arange(10)
 
# Auf 12 Elemente auffüllen, dann zu (3, 4) umformen
padded = np.pad(arr, (0, 2), constant_values=0)
print(padded.reshape(3, 4))
# [[0 1 2 3]
#  [4 5 6 7]
#  [8 9 0 0]]
  1. Verwenden Sie -1, damit NumPy eine Dimension für Sie berechnet und manuelle Rechenfehler vermieden werden.
import numpy as np
 
arr = np.arange(10)
print(arr.reshape(-1, 2))
# [[0 1]
#  [2 3]
#  [4 5]
#  [6 7]
#  [8 9]]

Fehler: "Expected 2D array, got 1D array instead"

Dieser scikit-learn-Fehler erscheint, wenn Sie ein 1D-Feature-Array übergeben. Die Lösung ist einfach:

import numpy as np
 
features = np.array([1.5, 2.3, 3.1, 4.7, 5.0])
 
# In Spaltenvektor umwandeln
features_2d = features.reshape(-1, 1)
print(features_2d.shape)
# (5, 1)

Praktische Beispiele

Daten für Scikit-Learn vorbereiten

scikit-learn erwartet Feature-Matrizen mit der Form (n_samples, n_features). So formen Sie Daten korrekt für eine einfache lineare Regression um:

import numpy as np
 
# Einzelnes Feature: Hausgrößen in Quadratfuß
sizes = np.array([850, 1200, 1500, 1800, 2100, 2400, 2800])
 
# Umformen zu (n_samples, 1) für sklearn
X = sizes.reshape(-1, 1)
print(X.shape)
# (7, 1)
 
# Zielvariable (Preise) ist bereits 1D, was sklearn akzeptiert
y = np.array([150000, 220000, 275000, 320000, 380000, 430000, 510000])
 
# Jetzt sind X und y bereit für sklearn
# from sklearn.linear_model import LinearRegression
# model = LinearRegression().fit(X, y)

Bilddaten umformen

Die Arbeit mit Bilddatensätzen erfordert häufig das Umformen zwischen flachen Vektoren und räumlichen Dimensionen:

import numpy as np
 
# Laden eines 28x28-Graustufenbilds als flaches Array simulieren (wie MNIST)
flat_image = np.random.randint(0, 256, size=784)
print(flat_image.shape)
# (784,)
 
# Zu 2D-Bild umformen
image_2d = flat_image.reshape(28, 28)
print(image_2d.shape)
# (28, 28)
 
# Einen Batch von 100 Bildern für die Eingabe eines neuronalen Netzwerks umformen
batch_flat = np.random.randint(0, 256, size=(100, 784))
batch_images = batch_flat.reshape(100, 28, 28, 1)  # Kanal-Dimension hinzufügen
print(batch_images.shape)
# (100, 28, 28, 1)

Transponieren mit Reshape (und warum Sie es nicht tun sollten)

Ein häufiger Fehler ist die Verwendung von reshape zum "Transponieren" einer Matrix. Reshape ordnet Elemente in Speicherreihenfolge um, was nicht dasselbe wie Transponieren ist.

import numpy as np
 
matrix = np.array([[1, 2, 3],
                   [4, 5, 6]])
 
# FALSCH: reshape(3, 2) transponiert NICHT
wrong = matrix.reshape(3, 2)
print("reshape(3,2):")
print(wrong)
# [[1 2]
#  [3 4]
#  [5 6]]
 
# RICHTIG: verwenden Sie .T oder np.transpose()
correct = matrix.T
print("Transponieren:")
print(correct)
# [[1 4]
#  [2 5]
#  [3 6]]

Mit NumPy Reshape in RunCell arbeiten

Wenn Sie häufig Arrays umformen und einen schnelleren Workflow möchten, ist RunCell (opens in a new tab) ein KI-Agent, der direkt in Jupyter-Notebooks läuft. Er ist für Data Scientists entwickelt, die täglich NumPy-, pandas- und scikit-learn-Code schreiben.

RunCell kann bei Reshape-Operationen auf verschiedene Weisen helfen:

  • Sofortiges Shape-Debugging. Wenn Sie auf einen Shape-Mismatch-Fehler stoßen, liest RunCell den Traceback und schlägt den korrekten reshape-Aufruf vor, einschließlich der richtigen Dimensionen und des order-Parameters.
  • Automatische Boilerplate-Generierung. Beschreiben Sie, was Sie brauchen, in natürlicher Sprache -- "forme dieses flache Array in einen Batch von 32x32-Bildern mit 3 Kanälen um" -- und RunCell schreibt den Code.
  • Alternativen erkunden. RunCell kann Ihnen zeigen, ob Sie reshape, np.expand_dims, np.newaxis oder np.squeeze verwenden sollten, abhängig von Ihrer spezifischen Situation.

Da RunCell direkt in Ihrer Jupyter-Umgebung arbeitet, behalten Sie die volle Kontrolle über Ihre Daten und Ihren Code, während Sie KI-gestützte Vorschläge genau dort erhalten, wo Sie sie brauchen.

FAQ

Was macht numpy reshape(-1)?

Der Aufruf von array.reshape(-1) flacht das Array in eine Dimension ab. Das -1 weist NumPy an, die Gesamtzahl der Elemente automatisch zu berechnen. Es ist äquivalent zu array.ravel() oder array.flatten(), wobei reshape(-1) wenn möglich eine Ansicht zurückgibt, während flatten() immer eine Kopie zurückgibt.

Ändert numpy reshape das ursprüngliche Array?

Nein. reshape() gibt ein neues Array-Objekt zurück. Wenn das zurückgegebene Array jedoch eine Ansicht ist (was normalerweise der Fall ist), ändert das Ändern des umgeformten Arrays auch das Original, da sie denselben Speicher teilen. Um dies zu vermeiden, rufen Sie .copy() auf dem Ergebnis auf.

Was ist der Unterschied zwischen reshape und flatten?

reshape() kann ein Array in jede kompatible Form konvertieren. flatten() konvertiert immer in ein 1D-Array und gibt immer eine Kopie zurück. ravel() konvertiert ebenfalls in 1D, gibt aber wenn möglich eine Ansicht zurück, ähnlich wie reshape(-1).

Kann ich einen pandas DataFrame mit numpy reshape umformen?

Nicht direkt. Sie müssen zuerst das zugrunde liegende NumPy-Array mit df.values oder df.to_numpy() extrahieren und es dann umformen. Für DataFrame-spezifische Umformungsoperationen verwenden Sie pandas-Methoden wie pivot(), melt(), stack() oder unstack().

Wie forme ich ein Array um, um eine neue Achse hinzuzufügen?

Sie können reshape() verwenden, aber np.expand_dims() oder np.newaxis ist übersichtlicher für das Hinzufügen einer einzelnen Dimension:

import numpy as np
 
arr = np.array([1, 2, 3])
 
# Mit reshape
print(arr.reshape(1, 3).shape)   # (1, 3)
print(arr.reshape(3, 1).shape)   # (3, 1)
 
# Mit np.newaxis (besser lesbar)
print(arr[np.newaxis, :].shape)  # (1, 3)
print(arr[:, np.newaxis].shape)  # (3, 1)

Fazit

numpy.reshape() ist eine der am häufigsten verwendeten Funktionen in der NumPy-Bibliothek. Sie ermöglicht die Konvertierung zwischen 1D-, 2D-, 3D- und höherdimensionalen Arrays, ohne Daten zu kopieren (in den meisten Fällen). Die wichtigsten Punkte zum Merken:

  • Die Gesamtzahl der Elemente muss vor und nach dem Umformen gleich bleiben.
  • Verwenden Sie -1 für eine Dimension, damit NumPy sie automatisch berechnet.
  • reshape() gibt normalerweise eine Ansicht zurück, keine Kopie. Änderungen an der Ansicht wirken sich auf das Original aus.
  • Die Standard-order='C' füllt Elemente Zeile für Zeile. Verwenden Sie order='F' für spaltenweise Daten aus MATLAB oder Fortran.
  • Wenn scikit-learn über 1D-Arrays klagt, ist .reshape(-1, 1) Ihre Lösung.

Beherrschen Sie diese Muster und Sie werden Shape-Fehler souverän bewältigen, egal ob Sie tabellarische Daten für maschinelles Lernen vorbereiten oder Bildtensoren für Deep Learning umformen.

📚