Warum Arrays, und was ein Array ist
Eine Python-Liste kann alles enthalten, was sie flexibel, aber für Zahlen langsam macht: Jedes Element ist ein eigenes Objekt. NumPy bringt das ndarray, einen Speicherblock mit Zahlen eines einzigen Typs hintereinander. Die Verarbeitung des ganzen Blocks in kompiliertem Code ist meist zehnmal und mehr schneller als eine Python-Schleife und braucht viel weniger Speicher. Fast jede quantitative Bibliothek (pandas, SciPy, scikit-learn) baut darauf auf. Importiert wird es üblicherweise als import numpy as np.
import numpy as np
# Create arrays
prices = np.array([184.25, 185.0, 183.2])
print(prices) # [184.25 185. 183.2 ]
print(np.zeros(3)) # [0. 0. 0.]
print(np.arange(0, 10, 3)) # [0 3 6 9]
print(np.linspace(0, 1, 5)) # [0. 0.25 0.5 0.75 1. ]
# An array knows its shape
table = np.array([[1, 2, 3], [4, 5, 6]])
print(table.shape, table.ndim, table.size) # (2, 3) 2 6Arrays erzeugen
np.array(liste) wandelt eine Liste (oder eine Liste von Listen für zwei Dimensionen) um. np.zeros(n) und np.ones(n) erzeugen gefüllte Arrays, und np.zeros((zeilen, spalten)) nimmt ein Form-Tupel. np.arange(start, stop, schritt) funktioniert wie range, erlaubt aber Float-Schritte und schließt stop aus; wegen der Rundung ist np.linspace(start, stop, num) vorzuziehen, das genau num gleichmäßig verteilte Punkte liefert und beide Enden einschließt. Jedes Array hat .shape (die Größe je Dimension), .ndim (Zahl der Dimensionen) und .size (Gesamtzahl der Elemente).
import numpy as np
# arange with floats can surprise; linspace gives exactly the points you ask for
print(len(np.arange(0, 1, 0.1))) # 10 (1.0 is excluded)
print(len(np.linspace(0, 1, 11))) # 11 (both ends included)
# Shapes and sizes
grid = np.zeros((3, 4))
print(grid.shape, grid.ndim, grid.size) # (3, 4) 2 12
print(np.ones(2) * 5) # [5. 5.]dtypes: ein Typ für das ganze Array
Jedes Array hat einen dtype: int64 (ganze Zahlen), float64 (Dezimalzahlen), bool und kleinere oder größere Varianten wie float32 oder int8. NumPy wählt den dtype aus den Daten: Ganzzahlen ergeben int64, eine einzige Dezimalzahl macht alles zu float64, und np.nan (not-a-number, die Markierung für fehlende Werte) ist ein Float und erzwingt daher float64. Wählen Sie den dtype selbst mit dtype=... oder wandeln Sie mit .astype(...) um, das ein neues Array liefert. Ein kleinerer dtype spart Speicher (float32 braucht die Hälfte von float64), kostet aber Genauigkeit.
import numpy as np
print(np.array([1, 2, 3]).dtype) # int64
print(np.array([1, 2.5, 3]).dtype) # float64 (one decimal upgrades everything)
print(np.array([True, False]).dtype) # bool
print(np.array([1, 2, np.nan])) # [ 1. 2. nan] (nan is a float)
# astype returns a new array; smaller dtypes use less memory
prices = np.zeros(1000)
print(prices.nbytes) # 8000
print(prices.astype(np.float32).nbytes) # 4000
print(np.array(["1.5", "2"], dtype=float)) # [1.5 2. ] (text converted to numbers)Fallstricke beim Umwandeln: Abschneiden und Überlauf
Das Umwandeln von Dezimalzahlen in Ganzzahlen mit .astype(int) schneidet zur Null hin ab, und Floats stellen die meisten Dezimalzahlen nicht exakt dar: 19.99 * 100 ist 1998.9999999999998 und wird zu 1998, einen Cent zu wenig. Um Preise in ganze Cent umzuwandeln, runden Sie zuerst: np.round(prices * 100).astype(np.int64). Ganzzahl-dtypes haben außerdem einen festen Bereich und laufen stillschweigend über: Ein int8 reicht von -128 bis 127, 100 * 2 wird also zu -56. Nutzen Sie int64 für Geld und Zählungen, und denken Sie daran, dass die Division von Ganzzahlen mit / stets Floats liefert, // dagegen abrundet.
import numpy as np
# Truncation: astype(int) cuts the decimals off
print(np.array([1.9, -1.9]).astype(int)) # [ 1 -1]
print(19.99 * 100, int(19.99 * 100)) # 1998.9999999999998 1998
print(np.round(np.array([19.99]) * 100).astype(np.int64)) # [1999]
# Overflow: an int8 wraps around silently
small = np.array([100, 50], dtype=np.int8)
print(small * 2) # [-56 100]
# / always gives floats, // floors
counts = np.array([1, 2, 3])
print(counts / 2, counts // 2) # [0.5 1. 1.5] [0 1 1].shape und .dtype jedes beteiligten Arrays aus: ein überraschendes int64, wo float64 erwartet wurde, oder die Form (5, 1) statt (5,) erklärt die meisten Fehler. Bauen Sie Arrays lieber mit NumPy-Funktionen (np.linspace, np.asarray, astype) als mit Python-Schleifen; die Labs lehnen Schleifen genau deshalb ab.np.array,zeros,ones,arange,linspaceerzeugen Arrays;.shape,.ndim,.sizebeschreiben sie.- Ein dtype pro Array:
int64,float64,bool;astypewandelt in ein neues Array um. astype(int)schneidet ab (vorher runden); kleine Ganzzahl-dtypes laufen still über;nanerzwingt Floats.
Als Nächstes: Arrays indizieren und slicen, um Zeilen, Spalten, Fenster und Werte auszuwählen, die eine Bedingung erfüllen.
Lab: Was bewertet wird
- Mit
make_gridgleichmäßig verteilte Punkte anlegen25 Pkt. - Mit
to_float_arraygemischte Rohwerte in Floats umwandeln25 Pkt. - Mit
describe_arrayForm, Größe und dtype angeben25 Pkt. - Mit
to_centsPreise sicher in ganze Cent umwandeln25 Pkt.