Das NumPy-Array
Kurz gesagt: Ein NumPy-Array (ndarray) enthält Zahlen eines einzigen Typs (dtype) mit einer Form und rechnet damit viel schneller als eine Python-Liste.
Problem
„Schlag auf jeden Preis die Mehrwertsteuer auf“
Der Shop hat 25 Produkte. Der Chef will die Preise mit Mehrwertsteuer: jeder Preis mal 1,2. Danach will er ein Jahr Verkäufe pro Tag: 25 Produkte an 365 Tagen, das sind 9.125 Zahlen.
Bisher lebten Zahlen in Python in einer Liste. Eine Liste rechnet aber nicht:
* 2 verdoppelt die Preise nicht, es wiederholt die Liste zweimal. * 1.2 ist ein Fehler. Bleibt eine for-Schleife für jede Rechnung, und bei 9.125 Zahlen, dann bei einer Million, wird der Code lang und langsam.
Die Idee
Ein Array: ein Block von Zahlen
Eine Liste ist eine Sammlung einzelner Objekte. Jeder ihrer Plätze enthält eine Adresse, und die Zahl selbst liegt woanders im Speicher, mit ihrer eigenen Python-„Hülle“. Deshalb kann eine Liste alles halten: eine Zahl, Text, eine andere Liste.
Die Datenanalyse braucht das nicht. Sie braucht viele Zahlen desselben Typs. NumPy ist die Bibliothek dafür, und ihr Kern ist das Array: Die Zahlen liegen nebeneinander in einem Block des Speichers, alle vom selben Typ. Hier sind eine Million Preise als Liste und als Array:
Die Liste braucht 20,2 MB und das Array 8,0 MB: 8 Byte pro Preis und nichts weiter. Die Sandbox ist 32-Bit. Auf einem gewöhnlichen 64-Bit-Computer sind Adressen und Hüllen größer, und die Liste wächst auf etwa 32 MB, während das Array bei 8 MB bleibt.
Ein Block gleichartiger Zahlen lässt sich auch schneller abarbeiten: NumPy läuft mit fertigem C-Code darüber, ohne bei jeder Zahl nach dem Typ zu fragen. Hier ist die Mehrwertsteuer auf eine Million Preise:
array * 1.2 multipliziert alle Preise auf einmal. In der Sandbox ist das Array mehrmals schneller als die Schleife. Auf einem gewöhnlichen Computer ist der Abstand das Zehnfache und mehr. Die genaue Zeit hängt vom Rechner ab, deshalb sagt der Code nur, was schneller ist.
Genauer, für Neugierige
import numpy as np ist die Gewohnheit aller, wie pd bei pandas. pandas selbst baut auf NumPy auf: Eine Spalte der Tabelle hält ihre Zahlen in einem Array. Was du hier lernst, gilt also auch für Tabellen.
Die Idee
Ein Array aus der Tabelle: dtype
Die Preise stehen schon in products.csv. to_numpy() nimmt eine Spalte der Tabelle als Array. Jedes Array kennt den Typ seiner Zahlen: Das ist der dtype.
prices[:5] liefert die ersten fünf, wie bei einer Liste. Ein Array wird ohne Kommas ausgegeben: [1.2 1.9 0.8 2.5 1.6].
float64: Dezimalzahlen, je 8 Byte (64 Bit). So sind die Preise.int64: ganze Zahlen, ebenfalls je 8 Byte. So ist der Bestand.
Sieh es dir an
Wenn sich Typen mischen
Für das ganze Array gibt es einen Typ. Was passiert, wenn du Verschiedenes hineinlegst?
- Ganze und Dezimalzahlen: Alle werden zu Dezimalzahlen.
40wird ohne Verlust zu40.0, umgekehrt würde 1.5 abgeschnitten. - Ein einziges Stück Text: Alles wird zu Text.
<U32bedeutet einen String von bis zu 32 Zeichen. Die Zahlen sind keine Zahlen mehr.
Genauer, für Neugierige
Schreibst du np.array([40, 25, 60]) in der Sandbox, ist der Typ int32, nicht int64. Die Standardart der ganzen Zahl richtet sich nach der Maschine, und die Sandbox ist 32-Bit. Auf deinem Computer ist es int64. Spalten, die mit pandas gelesen werden, sind auch hier int64. Für Mengen in einem Shop genügen beide Typen: int32 fasst Zahlen bis etwa 2,1 Milliarden.
Die Idee
Die Form: shape und ndim
Die Preise sind eine Reihe von Zahlen. Die Verkäufe pro Woche sind eine Tabelle: eine Zeile für jedes Produkt, eine Spalte für jede Woche. Ein Array kann beides sein.
shapeist die Form: wie viele Zahlen es in jeder Richtung gibt.ndimist die Zahl der Richtungen (Dimensionen).
Die Preise haben die Form (25,): eine Dimension mit 25 Zahlen. Das Komma steht da, weil eine Form immer ein Paar, ein Tripel und so weiter ist (ein Tupel), auch mit nur einer Zahl darin. Die Tabelle ist (3, 4): 3 Zeilen (die Produkte) und 4 Spalten (die Wochen). Zuerst die Zeilen, dann die Spalten, wie bei shape in pandas.
Probier es aus
Produkte und Wochen
qty enthält Stück pro Produkt (Zeilen) und pro Woche (Spalten). Lege die Zahl der Produkte in n_products und die Zahl der Wochen in n_weeks ab, aus der Form des Arrays genommen.
Lösung
import numpy as np
qty = np.array([
[4, 2, 5, 3],
[1, 0, 2, 2],
[6, 7, 5, 8],
])
n_products = qty.shape[0]
n_weeks = qty.shape[1]qty.shape ist (3, 4), also n_products = qty.shape[0] (3) und n_weeks = qty.shape[1] (4). len(qty) liefert nur die Zahl der Zeilen und qty.size die Zahl aller Zahlen: 12.
Die Idee
Fertige Arrays: arange und zeros
Oft kommt ein Array nicht aus einer Datei, du machst es selbst:
np.arange(start, ende)liefert aufeinanderfolgende Zahlen, wierange. Das Ende gehört nicht dazu.np.zeros(shape)liefert ein Array aus Nullen. Das ist praktisch für eine Tabelle, die du füllen wirst. Die Form einer Tabelle ist ein Paar:np.zeros((Zeilen, Spalten)), mit doppelten Klammern.
Die Tage laufen von 1 bis 365, also ist das Ende 366. Die Tabelle für ein Jahr Verkäufe ist (25, 365): 9.125 Nullen vom Typ float64, bereit für die Zahlen.
Übung
Die Preisliste und das Jahr
Lege days mit den Tagen von 1 bis 365 an und sales: eine Tabelle aus Nullen mit einer Zeile für jedes der 25 Produkte und einer Spalte für jeden Tag.
Lösung
import numpy as np
days = np.arange(1, 366)
sales = np.zeros((25, 365))days = np.arange(1, 366): Das Ende 366 gehört nicht dazu, der letzte Tag ist also 365. np.arange(365) beginnt bei 0. sales = np.zeros((25, 365)): zuerst die Zeilen (die Produkte), dann die Spalten (die Tage). np.zeros((365, 25)) ist auch eine Tabelle, aber gekippt.
Lege die Preise und den Bestand in eine Array-Tabelle mit zwei Zeilen: in der ersten die Preise, in der zweiten den Bestand. Lege den Typ der Tabelle in kind ab.
Lösung
import numpy as np
import pandas as pd
products = pd.read_csv('products.csv')
prices = products['price'].to_numpy()
stock = products['stock'].to_numpy()
table = np.array([prices, stock])
kind = table.dtypetable = np.array([prices, stock]) hat die Form (2, 25). Der Typ ist float64, obwohl der Bestand int64 war: Alles in einem Array hat einen Typ, und die Preise sind Dezimalzahlen. Deshalb erscheint der Bestand von 40 jetzt als 40.0.
Test
Teste dich
Verwandte Lektionen
Abschnitt „Verwandte Lektionen“- Baut auf: Die erste Tabelle
- Geht weiter in: Vektorisierung · Zusammenfassungen und fehlende Werte · Broadcasting: die Zahl, die Zeile und die Spalte · Series und DataFrame
- Aufgaben zum Thema: NumPy