Arrays umformen#
Manchmal ist das Problem bei erhobenen Daten nicht, dass sie durch ein Schichtsystem in kleineren Matrixen oder Vektoren aufgeteilt sind, sondern dass sie in einem ungünstigen Format abgespeichert wurden.
Um die NextBike Daten, die der Lehrstuhl für wissenschatliches Rechnen erhoben hat, gegenzuprüfen, hat der Lehrstuhl für stochastische Numerik unabhängig von diesem ebenfalls die NextBike Ausleihen gezählt. Sie haben die Zahlen allerdings anders vermerkt. Es gab einen Zettel, der bei Schichtende an die nächste Person weitergegeben wurde. Auf diesem Zettel wurden alle Zahlen nebeneinander notiert:
Das heißt die Daten haben nicht die Form:
Unser Ziel in diesem Kapitel ist es, auch diese erhobenen Daten in unsere übersichtliche Matrixform zu bringen.
Arrays in eine Matrix überführen#
In NumPy können Sie mit der Funktion \(\texttt{np.reshape}\) ein Array in eine Matrix überführen, die die gleichen Einträge hat, aber in einer anderen Anordung. Der Befehl \(\texttt{np.reshape(arr, (m,n))}\) formt das Array \(\texttt{arr}\) in eine \(m \times n\) Matrix um.
Mit \(\texttt{np.reshape}\) können Sie ein Array nicht nur in Matrizen, also ein zweidimensionales Arrays umwandeln, sondern auch in beliebig dimensionale Arrays. Dazu müssen Sie lediglich die gewünschte Größe entsprechend setzen.
import numpy as np
a1 = np.arange(1, 13)
shape_2D = (3, 4)
shape_3D = (2, 3, 2)
a1_3x4 = np.reshape(a1, shape_2D)
a1_2x3x2 = np.reshape(a1, shape_3D)
print(a1_3x4)
print(a1_2x3x2)
Achtung
Achten Sie darauf, dass die Anzahl der Element des Arrays \(\texttt{arr}\) gleich der Anzahl der Element der gewünschten Form ist. Wenn Sie ein Array in eine \(m \times n\) Matrix umformen möchten, muss also \(\texttt{np.size(arr)} = m \cdot n\) gelten. Andernfalls gibt Python eine Fehlermeldung aus!
Aufgabe 1.1
Erstellen Sie ausgehend von den erhobenen Daten \(\texttt{rohdaten}\) die Matrix \(\texttt{W1}\), welche folgende Form haben soll:
rohdaten = np.array([[32, 47, 42, 42, 22, 21, 14, 50, 36, 18, 39, 50, 37, 76]])
# Ihr Code
Hinweis
Nutzen die Funktion \(\texttt{reshape}\) und achten Sie auf die richtige Anzahl an Spalten und Zeilen.
Lösung
W1 = reshape(rohdaten, (2, 7))
W1 = np.hstack(
(
np.array([[""], ["Vormittag"], ["Nachmittag"]]),
np.vstack((np.array([["Mo", "Di", "Mi", "Do", "Fr", "Sa", "So"]]), W1)),
)
)
print(W1)
Die Funktion \(\texttt{np.reshape}\) bietet ebenfalls die Möglichkeit nur eine Dimension vorzugeben. Der Ausdruck \(\texttt{np.reshape(-1,n)}\) formt eine Matrix oder einen Vektor in eine \(x \times n\) Matrix um, wobei \(x\) automatisch so gewählt wird, dass die die Anzahl der Einträge vor und nach der Umformung übereinstimmen. Analog funktioniert der Befehl \(\texttt{np.reshape(m,-1)}\), der eine \(m \times x\) Matrix erzeugt.
a1_3x4_matrix_spalten = np.reshape(a1, (-1, 4))
a1_3x4_matrix_zeilen = np.reshape(a1, (3, -1))
print(a1_3x4_matrix_spalten)
print(a1_3x4_matrix_zeilen)
Aufgabe 1.2
Erstellen Sie erneut die Matrix \(\texttt{W1}\) mit Hilfe der erhobenen Daten \(\texttt{rohdaten}\) in Vektorform, indem Sie nur eine Dimension vorgeben
rohdaten = np.array([[32, 47, 42, 42, 22, 21, 14, 50, 36, 18, 39, 50, 37, 76]])
# Ihr Code
Hinweis
Nutzen die Funktion \(\texttt{np.reshape}\) und achten Sie auf die richtige Anzahl an Spalten oder Zeilen.
Lösung
W1 = np.reshape(rohdaten, (-1, 7))
# Alternativ: W1 = np.reshape(rohdaten, (2,-1))
W1 = np.hstack(
(
np.array([[""], ["Vormittag"], ["Nachmittag"]]),
np.vstack((np.array([["Mo", "Di", "Mi", "Do", "Fr", "Sa", "So"]]), W1)),
)
)
print(W1)
Array in einen Vektor überführen#
Mit dem \(\texttt{np.ravel()}\) Befehl kann man eine beliebige Matrix wieder in einen Vektor umformen.
a1_kopie = np.ravel(a1_3x4)
print(a1_kopie)
Aufgabe 2.1
Extrahieren Sie aus der Matrix \(\texttt{W1}\) aus Aufgabe 1.2 wieder die Rohdaten und speichern Sie dies in \(\texttt{rohdaten_kopie}\).
# Ihr Code
Hinweis
Verwenden Sie \(\texttt{np.ravel()}\). Achten Sie darauf nur die relevanten Einträge aus \(\texttt{W1}\) zu verwenden.
Lösung
rohdaten_kopie = np.ravel(W1[1:,1:])
print(rohdaten_kopie)
Sie haben vielleicht bemerkt, dass jeder Eintrag als \(\texttt{string}\) gespeichert ist. Dies wurde von NumPy automatisch gemacht, als wir eine Zeile/Spalte mit Strings hinzugefügt haben. Um dies rückgängig zu machen, kann der Befehl \(\texttt{.astype(int)}\) an ein Array \(\texttt{arr}\) angehängt werden. Durch \(\texttt{arr.astype(int)}\) werden alle Einträge in \(\texttt{arr}\) wieder in ganze Zahlen umgewandelt.
Aufgabe 2.2
Wandeln Sie \(\texttt{rohdaten_kopie}\) in einen Vektor mit ganzzahligen Einträgen um.
# Ihr Code
Hinweis
Verwenden Sie \(\texttt{.astype(int)}\).
Lösung
rohdaten_kopie = rohdaten_kopie.astype(int)
print(rohdaten_kopie)
Bisher haben wir die Matrizen immer zeilenweise gefüllt. Das heißt, die erste Zeile besteht aus den ersten Einträgen des Vektors, die Zweite aus den Einträgen danach usw. Diese Anordnung nennt man row-major order. Natürlich kann man eine Matrix auch spaltenweise füllen. Das nennt man auch column-major order. Dazu muss \(\texttt{np.reshape}\) die zusätzliche Eingabe \(\texttt{order = 'F'}\) hinzugefügt werden.
a1_3x4_matrix_columnwise = np.reshape(a1, (3, 4), order='F')
print(a1_3x4_matrix_columnwise)