NumPy-Arrays und vektorisiertes Rechnen
MittelEinheit 1 von 8 in Kurs: Datenanalyse mit Python – NumPy, pandas und Matplotlib
Was du lernst
- Erstelle NumPy-Arrays aus Python-Daten und mit den Erzeugungsfunktionen von NumPy, beschreibe ein Array anhand seiner Form und seines Datentyps und wähle Datentypen aus und wandle sie um, ohne versehentlich Informationen zu verlieren.
- Erklären, was ein NumPy-Array ist und wie es sich von einer Liste unterscheidetBeschreibe ein Array anhand seiner Dimensionen, Form, Elementanzahl und seines Datentyps und erkläre, warum sich Arrays anders verhalten und eine andere Leistung aufweisen als Python-Listen.
- Arrays aus Listen und mit den Erzeugungsfunktionen von NumPy erstellenWandle Listen in Arrays um und erzeuge gefüllte Arrays, Zahlenfolgen und äquidistante Gitter mit der benötigten Form und dem passenden Typ.
- Datentypen auswählen, prüfen und umwandelnLies und lege den Datentyp eines Arrays fest, sage den von NumPy gewählten Typ voraus und wandle Typen um, ohne Nachkommastellen abzuschneiden, einen Überlauf zu verursachen oder fehlende Werte zu verlieren.
- Erklären, was ein NumPy-Array ist und wie es sich von einer Liste unterscheidet
- Wähle einzelne Werte, Zeilen, Spalten und Blöcke aus, nutze Positionslisten oder Bedingungen und erkenne, wann eine Auswahl ihre Daten mit dem ursprünglichen Array teilt.
- Ein- und zweidimensionale Arrays indizieren und mit Slices auswählenNutze Positionen und Slices, jeweils eine pro Achse, um Elemente, Zeilen, Spalten und Blöcke zu lesen und zu ändern.
- Mit Positionslisten auswählen und Sichten von Kopien unterscheidenWähle beliebige Elemente, Zeilen oder Spalten mit Ganzzahl-Arrays aus und sage voraus, ob sich ein Ergebnis den Speicher mit dem ursprünglichen Array teilt.
- Mit booleschen Masken und np.where nach Bedingungen filternErstelle aus Vergleichen Wahrheitswertmasken, kombiniere sie und nutze sie zum Filtern, Zählen, Ersetzen und Auswählen von Werten.
- Ein- und zweidimensionale Arrays indizieren und mit Slices auswählen
- Ordne dieselben Werte in einer neuen Form an, vertausche Zeilen und Spalten, füge Achsen der Länge 1 hinzu oder entferne sie und füge Arrays entlang einer Achse zusammen oder teile sie auf.
- Die Form eines Arrays ändern und seine Achsen vertauschenForme Arrays um, flache sie ab und transponiere sie. Füge Achsen der Länge 1 hinzu oder entferne sie und sage dabei die Reihenfolge der Werte voraus.
- Arrays zusammenfügen und aufteilenKombiniere Arrays entlang einer vorhandenen oder einer neuen Achse und zerlege ein Array in Teile. Prüfe dabei, ob die Formen passen.
- Die Form eines Arrays ändern und seine Achsen vertauschen
- Schreibe Berechnungen für ganze Arrays statt Schleifen für einzelne Elemente, wende die universellen Funktionen von NumPy an und kombiniere Arrays unterschiedlicher Form nach den Broadcasting-Regeln.
- Elementweise rechnen statt Schleifen zu verwendenNutze arithmetische Operatoren und Vergleichsoperatoren auf ganzen Arrays und verstehe, wie sie Formen, Division durch null und direkte Aktualisierungen behandeln.
- Universelle Funktionen auf ganze Arrays anwendenNutze die elementweisen mathematischen Funktionen von NumPy, darunter Rundungsfunktionen und Funktionen für zwei Arrays, und gehe mit Werten außerhalb des Definitionsbereichs einer Funktion um.
- Arrays unterschiedlicher Form durch Broadcasting kombinierenWende die Broadcasting-Regeln an, um vorherzusagen, ob sich zwei Formen kombinieren lassen und welche Form entsteht. Behebe Formfehler durch Hinzufügen einer Achse.
- Elementweise rechnen statt Schleifen zu verwenden
- Reduziere Arrays auf Summen, Mittelwerte, Extremwerte, Streuungsmaße, Mediane und Anzahlen, für das ganze Array oder entlang einer gewählten Achse, und berücksichtige fehlende Werte und Teilmengen korrekt.
- Ein ganzes Array oder entlang einer Achse aggregierenBerechne Summen, Mittelwerte, Extremwerte, Positionen, kumulative Summen und Streuungsmaße für das ganze Array oder pro Zeile oder Spalte und sage die Form des Ergebnisses voraus.
- Mediane, Perzentile, Sortierung und unterschiedliche Werte nutzenBeschreibe Lage und Streuung von Daten mit rangbasierten Kennwerten, sortiere Werte und zusammengehörige Arrays und zähle unterschiedliche Werte.
- Daten unter Berücksichtigung fehlender Werte und Bedingungen zusammenfassenFinde, zähle, entferne und fülle fehlende Werte, nutze Aggregationen unter Ausschluss von NaN und fasse nur die Werte zusammen, die eine Bedingung erfüllen oder zu einer Gruppe gehören.
- Ein ganzes Array oder entlang einer Achse aggregieren
- Erstelle einen Zufallszahlengenerator mit Startwert, ziehe reproduzierbare Stichproben aus gängigen Verteilungen, mische Daten und ziehe Stichproben daraus und schätze Ergebnisse mit vektorisierten Simulationen.
- Mit einem Generator reproduzierbare Zufallsstichproben ziehenErstelle einen Generator mit einem Startwert, ziehe Ganzzahlen, Dezimalzahlen, normalverteilte Werte und Stichproben aus einer Liste, mische Daten und halte Ergebnisse reproduzierbar.
- Vektorisierte Simulationen durchführenSchätze Wahrscheinlichkeiten und langfristiges Verhalten, indem du alle Zufallswerte auf einmal ziehst und mit Array-Operationen zusammenfasst.
- Mit einem Generator reproduzierbare Zufallsstichproben ziehen
NumPy-Arrays einfach erklärt
1Arrays erstellen und ihre Datentypen festlegen
Mit numerischen Daten lässt sich leichter arbeiten, wenn ihre Struktur und ihr Speichertyp klar sind. Erstelle Arrays aus vorhandenen Werten oder anhand einer geplanten Form und lies dann ihre Dimensionen, Elementanzahl und ihren Datentyp ab. Wähle Erzeugungsfunktionen passend zu deiner Eingabe und sieh dir an, wie sich Umwandlung, Rundung, Überlauf und fehlende Werte darauf auswirken, was das Array tatsächlich speichert. Diese Entscheidungen bestimmen, ob spätere Berechnungen die benötigten Informationen erhalten.
1.1 Erklären, was ein NumPy-Array ist und wie es sich von einer Liste unterscheidet
NumPy speichert numerische Daten in Arrays, sodass ein Ausdruck auf viele Werte angewendet werden kann. Importiere NumPy mit import numpy as np; der Kurzname np wird üblicherweise verwendet, um seine Funktionen aufzurufen.
Die Struktur eines Arrays ablesen
Ein ndarray ist ein rechteckiges Gitter, dessen Elemente denselben Datentyp haben. Eine Dimension wird auch Achse genannt. Beginne mit einer kleinen Tabelle:
import numpy as np
a = np.array([[1, 2, 3], [4, 5, 6]])
Ihre Attribute beantworten vier verschiedene Fragen:
| Attribut | Bedeutung | Wert für a |
|---|---|---|
ndim | Anzahl der Achsen | 2 |
shape | Länge jeder Achse | (2, 3) |
size | Anzahl aller Elemente | 6 |
dtype | Typ jedes Elements | Auf einem 64-Bit-Computer üblicherweise int64 |
Achse 0 indiziert Zeilen, Achse 1 indiziert Spalten. Eine Datentabelle mit einer Zeile pro Person und Spalten für Größe, Masse und Alter hätte für 100 Personen die Form (100, 3). Das Produkt der Formeinträge ergibt die Elementanzahl.
Ein Vektor hat keine Zeilen- oder Spaltenachse
np.array([2, 4, 6, 8]) hat die Form (4,) und eine Achse. Das Komma macht daraus ein Tupel mit einem Eintrag. Die Form (1, 4) hat zwei Achsen: eine Zeile und vier Spalten. Auch die Form (4, 1) hat zwei Achsen, aber vier Zeilen und eine Spalte. Diese Arrays enthalten vier Werte, verhalten sich aber bei der Kombination mit anderen Arrays unterschiedlich. np.array(7) ist ein nulldimensionales Array: Seine Form ist () und sein ndim ist 0.
Arrays ändern die Bedeutung von Operatoren
Eine Liste ist ein allgemeiner Python-Container. Ein Array ist für Berechnungen an entsprechenden Positionen ausgelegt.
| Ausdruck | Ergebnis |
|---|---|
[1, 2, 3] * 2 | [1, 2, 3, 1, 2, 3] |
np.array([1, 2, 3]) * 2 | array([2, 4, 6]) |
[1, 2] + [3, 4] | [1, 2, 3, 4] |
np.array([1, 2]) + np.array([3, 4]) | array([4, 6]) |
Bei der Array-Addition wird 1 mit 3 und 2 mit 4 kombiniert. Das Array behält seine Größe.
Warum numerische Arrays effizient sind
Ein neu erstelltes numerisches Array speichert Werte desselben Datentyps gemeinsam im Speicher. NumPy durchläuft diese Werte in kompiliertem Code und vermeidet so für jede Zahl eine separate Operation auf Python-Ebene. Eine Million float64-Werte belegen 8.000.000 Byte Elementspeicher, der bei einem Array dieser Größe über a.nbytes abrufbar ist. Eine Python-Liste speichert zusätzlich Referenzen auf Python-Objekte und benötigt daher erheblich mehr Platz. Der Geschwindigkeitsgewinn hängt von der Berechnung und dem Computer ab.
Die Größe eines Arrays wächst nicht durch eine append-Methode, die es direkt ändert. np.append(a, value) reserviert ein neues Array. Für Daten, die einzeln erfasst werden, erstelle eine Python-Liste und wandle sie einmal um. Verschachtelte Eingaben müssen rechteckig sein: np.array([[1, 2], [3]]) löst einen ValueError aus, weil die Zeilen unterschiedlich lang sind.
Angezeigte Ergebnisse erkennen
print(np.array([1, 2, 3])) zeigt [1 2 3]. Eine interaktive Anzeige verwendet array([1, 2, 3]). Für np.array([5, 6])[0] zeigt NumPy 2 auf einem 64-Bit-Computer np.int64(5) an; bei Rechnungen verhält sich der Wert wie die Zahl 5.
Wichtige Erkenntnisse
- Die Form gibt die Länge jeder Achse an; die Elementanzahl zählt alle Elemente.
- Eine 1-dimensionale Form wie
(4,)unterscheidet sich von einer 2-dimensionalen Zeile oder Spalte. - Array-Arithmetik wirkt auf Werte an entsprechenden Positionen.
- Numerische Arrays speichern einen Datentyp und unterstützen effiziente kompilierte Berechnungen.
- Verschachtelte Eingaben müssen gleich lange Zeilen haben.
1.2 Arrays aus Listen und mit den Erzeugungsfunktionen von NumPy erstellen
Wähle eine Erzeugungsfunktion danach aus, was du kennst: die tatsächlichen Werte, eine Form und einen Füllwert, eine Schrittweite oder eine benötigte Anzahl von Punkten. So zeigt der Code, wie die Daten aufgebaut werden sollen.
Mit Werten oder einer Form beginnen
np.array([3, 1, 4]) erstellt einen Vektor. Eine Liste gleich langer Listen erstellt eine Tabelle. Übergib die Werte als eine Sequenz; np.array(1, 2, 3) übergibt nicht korrekt drei Elemente.
| Funktion | Beispiel | Was sie erstellt |
|---|---|---|
np.zeros | np.zeros((3, 4)) | Drei Zeilen mit je vier Nullen |
np.ones | np.ones((2, 3)) | Zwei Zeilen mit je drei Einsen |
np.full | np.full((2, 2), 7) | Ein mit 7 gefülltes 2 × 2 Array |
np.empty | np.empty((3, 4)) | Reservierter, nicht initialisierter Speicher |
Bei einer mehrdimensionalen Form sind die Klammern wichtig. np.zeros((2, 3)) übergibt ein Tupel. Bei np.zeros(2, 3) übergibt Python 3 als Datentyp-Argument, was einen Typfehler verursacht. Nullen und Einsen verwenden standardmäßig float64; full leitet seinen Datentyp aus dem Füllwert ab. Füge dtype=int hinzu, wenn du Ganzzahlen speichern musst.
empty garantiert weder Nullen noch sinnvolle Anfangswerte. Lies erst daraus, nachdem du jedem Element, das du verwenden wirst, einen Wert zugewiesen hast. zeros ist eine einfachere Wahl, wenn ein anfänglicher Wert von null sinnvoll ist.
Eine Schrittweite oder eine Punktanzahl wählen
np.arange(start, stop, step) folgt dem Schrittprinzip von Pythons range. np.arange(2, 11, 3) ergibt [2 5 8]: Beginne bei 2 und addiere 3, solange du unter 11 bleibst. Mit einem Argument beginnt np.arange(5) bei 0 und ergibt [0 1 2 3 4].
Gleitkomma-Schrittweiten können zu überraschenden Endpunkten führen. Beispielsweise enthält np.arange(1, 1.3, 0.1) den angezeigten Wert 1,3, weil die binäre Rundung die Berechnung der Folge beeinflusst. Für ein Dezimalgitter mit fester Punktanzahl verwende linspace:
grid = np.linspace(0, 1, 5)
# array([0. , 0.25, 0.5 , 0.75, 1. ])
Beide Endpunkte sind standardmäßig eingeschlossen. Fünf Punkte ergeben vier Abstände. Zehn Punkte zwischen 0 und 1 ergeben neun Abstände, ihr Abstand beträgt also etwa 0,111; Schritte von 0,1 benötigen 11 Punkte.
Eine vorhandene Struktur wiederverwenden
np.zeros_like(a), np.ones_like(a) und np.full_like(a, value) erstellen neue Arrays mit der Form und dem Datentyp von a. Der übernommene Datentyp ist wichtig: Füllst du eine Ganzzahlvorlage mit einer Dezimalzahl, kann der Nachkommateil verloren gehen, sofern du keinen Gleitkommatyp anforderst. np.eye(3) erstellt eine quadratische Einheitsmatrix mit Einsen auf der Diagonalen und Nullen an den übrigen Stellen.
Eine Datentabelle einmalig anlegen
Für Niederschlag in Millimetern an drei Stationen über vier Wochen:
rain = np.zeros((3, 4))
rain[0] = [12.0, 0.0, 5.5, 8.0]
Die erste Zuweisung füllt eine Zeile und erhält die Form (3, 4). Ist die Anzahl der Messwerte bekannt, vermeidest du durch das Reservieren der vollständigen Tabelle, wiederholt größere Arrays anzulegen. Ist die Menge der Eingaben unbekannt, sammle die Werte in einer Liste und rufe np.array auf, sobald die Sammlung abgeschlossen ist.
Wichtige Erkenntnisse
- Übergib eine mehrdimensionale Form als Tupel.
arangelegt eine Schrittweite fest;linspacelegt eine Punktanzahl fest.linspaceschließt standardmäßig beide Endpunkte ein.emptymuss gefüllt werden, bevor seine Werte verwendet werden.- Die like-Funktionen übernehmen sowohl Form als auch Datentyp.
- Lege eine bekannte endgültige Form einmalig an.
1.3 Datentypen auswählen, prüfen und umwandeln
Der Datentyp eines Arrays bestimmt, was es speichern kann und wie viel Speicher jeder Wert benötigt. Die Wahl des richtigen Typs verhindert auch, dass bei Berechnungen unbemerkt Informationen verloren gehen.
Den Speichertyp prüfen
int64 speichert 64-Bit-Ganzzahlen, float64 speichert binäre Gleitkommazahlen und bool speichert Wahrheitswerte. Unicode-Datentypen wie <U5 speichern Text mit einer maximalen Zeichenanzahl. a.itemsize gibt die Byte pro Element an; a.nbytes ist a.size * a.itemsize. Ein float64 belegt 8 Byte und hat eine Genauigkeit von etwa 15 signifikanten Dezimalstellen.
Auf typischen 64-Bit-Computern werden ganzzahlige Eingaben als 64-Bit-Ganzzahlen gespeichert. NumPy 2 verwendet diesen Standard auch unter 64-Bit-Windows. Dezimale Eingaben ergeben normalerweise float64.
Die Typinferenz wählt einen gemeinsamen Typ
np.array([1, 2.5]) wird zu [1. 2.5]: Die Ganzzahl wird als Gleitkommazahl dargestellt. np.array([True, 2]) wird zu [1 2]. Werden Zahlen und Text gemischt, kann das gesamte Array zu Text werden, sodass ein Eintrag wie 'n/a' spätere Rechnungen scheitern lassen kann. Prüfe dtype, wenn sich scheinbar numerische Daten nicht addieren oder multiplizieren lassen.
Bewusst umwandeln
astype gibt eine umgewandelte Kopie zurück:
x = np.array([1.7, -1.7, 2.5])
whole = x.astype(int)
# array([ 1, -1, 2])
Diese Umwandlung schneidet Nachkommastellen in Richtung null ab; sie rundet nicht. np.round(x).astype(int) ergibt [2 -2 2], weil genaue Hälften zur nächsten geraden Zahl gerundet werden. Text wie '1.5' lässt sich mit astype(float) umwandeln, aber 'n/a' löst einen ValueError aus. Bereinige Platzhalter vor der Umwandlung.
Zuweisungen verwenden den Datentyp des Ziels. Nach a = np.array([1, 2, 3]) speichert die Zuweisung a[0] = 9.9 ohne Warnung den Wert 9. Wenn du zuerst das gesamte Array in Gleitkommazahlen umwandelst, bleiben bei späteren Zuweisungen die Nachkommastellen erhalten.
Ganzzahlen fester Breite können überlaufen
Ein int8 speichert Werte von −128 bis 127; ein uint8 speichert 0 bis 255. Das Addieren zweier uint8-Arrays mit 250 und 10 ergibt durch Überlauf 4. Das Multiplizieren eines int8-Arrays mit dem Wert 100 mit 2 ergibt −56. Eine Python-Ganzzahl, die nicht in den Array-Typ passt, etwa 300 bei der Addition zu einem int8-Array in NumPy 2, löst dagegen einen OverflowError aus. Wandle kleine Ganzzahltypen vor Berechnungen, die ihren Wertebereich überschreiten können, in größere um.
Division und angenäherte Dezimalzahlen
| Operation | Beispiel | Ergebnis |
|---|---|---|
| Division | np.array([7, 8]) / 2 | [3.5 4.] |
| Ganzzahldivision | np.array([7, -7]) // 2 | [3 -4] |
| Rest | np.array([7, -7]) % 2 | [1 1] |
Die Ganzzahldivision rundet in Richtung minus unendlich ab. Bei negativen Ergebnissen unterscheidet sich das vom Abschneiden der Nachkommastellen. Die Division gibt bei ganzzahligen Eingaben Gleitkommaergebnisse zurück.
Viele Dezimalbrüche sind in binärer Darstellung Näherungen. 0.1 + 0.2 == 0.3 ist falsch; np.isclose vergleicht entsprechende Werte mit einer Toleranz, und np.allclose gibt eine Antwort für das ganze Array.
Das Fehlwertkennzeichen np.nan ist eine Gleitkommazahl. Ganzzahl-Arrays können es nicht speichern. np.array([1, 2, np.nan]) wird daher zu einem Gleitkomma-Array; die Umwandlung fehlender Werte in Ganzzahlen behebt sie nicht und kann bedeutungslose Ergebnisse liefern.
Wichtige Erkenntnisse
- Ein Datentyp bestimmt alle Elemente, einschließlich später zugewiesener Werte.
astype(int)schneidet Nachkommastellen in Richtung null ab; Runden ist ein separater Schritt.- Kleine Ganzzahlen fester Breite können bei Rechnungen überlaufen.
- Vergleiche angenäherte Dezimalzahlen mit einer Toleranz.
- NaN benötigt einen Gleitkomma-Datentyp.
2Daten in Arrays auswählen und filtern
Eine Analyse benötigt selten jeden Wert genau in seiner ursprünglichen Reihenfolge. Wähle einzelne Positionen, regelmäßige Slices, beliebige Datensätze oder Einträge aus, die eine Bedingung erfüllen. Prüfe vor einer Bearbeitung, ob ein Ergebnis seinen Speicher mit der Quelle teilt. Mit booleschen Masken kannst du dieselbe Auswahlregel zum Filtern, Ersetzen, Zählen und Berechnen von Anteilen nutzen und vollständige Datensätze erhalten, wenn deine Fragestellung dies erfordert.
2.1 Ein- und zweidimensionale Arrays indizieren und mit Slices auswählen
Indizierung findet Werte anhand ihrer Position. Slicing wählt eine regelmäßige Folge von Positionen aus. Schreibe bei einer Tabelle für jede Achse eine eigene Auswahl, sodass der Code angibt, welche Zeilen und welche Spalten du benötigst.
Einen Vektor lesen
Für a = np.array([10, 20, 30, 40, 50]) enthält Position 0 den Wert 10 und Position −1 den Wert 50. Ein Slice hat die Form start:stop:step, wobei der Stoppwert ausgeschlossen ist:
| Auswahl | Ergebnis |
|---|---|
a[1:4] | [20 30 40] |
a[::2] | [10 30 50] |
a[::-1] | [50 40 30 20 10] |
a[3:10] | [40 50] |
Wenn du Start oder Stopp auslässt, reicht der Slice bis zum jeweiligen Ende. Ein Slice kann über das Array hinausreichen und wird automatisch gekürzt. Eine einzelne ungültige Position wie a[5] löst einen IndexError aus.
Für jede Tabellenachse eine eigene Auswahl angeben
m = np.array([[1, 2, 3],
[4, 5, 6],
[7, 8, 9]])
m[1, 2] liest Zeile 1, Spalte 2 und ergibt 6. Das Komma trennt die Achsen. Ein Doppelpunkt allein wählt die gesamte Achse aus: m[0, :] ergibt die erste Zeile [1 2 3], und m[:, 1] ergibt die zweite Spalte [2 5 8]. Für einen Block wählt m[:2, 1:] die Zeilen 0 und 1 und die Spalten 1 und 2 aus und ergibt [[2 3] [5 6]].
Behandle die wiederholte Indizierung mit eckigen Klammern nicht als gleichbedeutend mit der Indizierung per Komma. m[1][2] findet zufällig denselben Skalar wie m[1, 2]. Aber m[:][0] nimmt zuerst alle Zeilen und wählt dann die erste Zeile aus. Es wählt nicht die erste Spalte aus; das tut m[:, 0].
Vorhersagen, welche Achsen erhalten bleiben
Ein einzelner Ganzzahlindex entfernt seine Achse. Ein Slice erhält seine Achse, selbst wenn nur eine Position ausgewählt wird. Daher hat m[:, 1] die Form (3,), während m[:, 1:2] die Form (3, 1) hat. Beide wählen 2, 5 und 8 aus, aber nur die zweite Variante erhält eine Spaltenachse. Dieser Unterschied wird wichtig, wenn Arrays mit anderen Formen subtrahiert oder multipliziert werden.
Dieselbe Regel gilt auch über Tabellen hinaus. Wenn t.shape gleich (2, 3, 4) ist, hat t[0] die Form (3, 4), t[0, 1] die Form (4,) und t[:, :, 0] die Form (2, 3). Alle am Ende des Index ausgelassenen Achsen werden vollständig ausgewählt.
Die ausgewählten Positionen ändern
Eine Zuweisung über einen Index schreibt in das vorhandene Array. a[1:3] = 0 ersetzt beide ausgewählten Werte durch null; der Skalar wird auf die gesamte Auswahl angewendet. m[0] = [0, 0, 0] ersetzt eine vollständige Zeile. Die zugewiesenen Werte müssen zur Form der Auswahl passen und werden in deren Datentyp umgewandelt.
Für vier Lernende und drei Tests:
scores = np.array([[78, 85, 92], [64, 70, 58],
[88, 91, 95], [72, 68, 80]])
scores[2] ist das Ergebnis der dritten Person [88 91 95]. scores[:, -1] ergibt die Ergebnisse des letzten Tests [92 58 95 80]. scores[1:3, :2] ergibt [[64 70] [88 91]]: zwei Lernende mit jeweils zwei Testspalten.
Wichtige Erkenntnisse
- Indizes beginnen bei 0; negative Indizes zählen vom Ende aus.
- Slices schließen die Stoppposition aus und können am Rand eines Arrays gekürzt werden.
- Verwende durch Kommas getrennte Auswahlen für separate Achsen.
- Ein Ganzzahlindex entfernt eine Achse; ein Slice erhält sie.
- Eine Zuweisung über einen Index ändert die ausgewählten Werte.
2.2 Mit Positionslisten auswählen und Sichten von Kopien unterscheiden
Eine Auswahl kann ihre Daten mit dem ursprünglichen Array teilen oder unabhängige Daten besitzen. Wenn du weißt, was vorliegt, verhinderst du, dass Änderungen an einer kleinen Auswahl unerwartet eine größere Tabelle verändern.
Alias, Sicht und Kopie unterscheiden
| Code | Beziehung | Auswirkung einer Änderung an b |
|---|---|---|
b = a | Zwei Namen für ein Objekt | Ändert a |
b = a[2:5] | Eine Slice-Sicht mit gemeinsam genutzten Daten | Ändert den entsprechenden Teil von a |
b = a[2:5].copy() | Unabhängige Daten | Lässt a unverändert |
Für a = np.arange(6) und b = a[2:5] macht die Zuweisung b[0] = 99 aus a den Wert [0 1 99 3 4 5]. Die erste Position der Sicht bezieht sich auf Position 2 im Original. Das unterscheidet sich vom Slicing einer Python-Liste, bei dem eine neue Liste entsteht.
Kopiere vor der Bearbeitung, wenn das Original unverändert bleiben muss. Eine kleine, aufbewahrte Sicht kann außerdem einen großen ursprünglichen Datenpuffer im Speicher halten; eine Kopie dieses kleinen Teils ist unabhängig davon.
Beliebige Positionen auswählen
Fancy Indexing verwendet eine Ganzzahlliste oder ein Ganzzahl-Array. Es erlaubt eine andere Reihenfolge und wiederholte Positionen:
a = np.array([10, 20, 30, 40, 50])
a[[4, 0, 0]]
# array([50, 10, 10])
Für m = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]]) wählt m[[0, 2]] die erste und dritte Zeile aus. m[:, [2, 0]] wählt die letzte und die erste Spalte in dieser Reihenfolge aus und ergibt [[3 1] [6 4] [9 7]].
Zwei Ganzzahllisten in einem Index wählen Koordinatenpaare aus. m[[0, 2], [1, 2]] verbindet Zeile 0 mit Spalte 1 und Zeile 2 mit Spalte 2 und ergibt [2 9]. Es werden nicht alle Kombinationen ausgewählt. Für den Block aus beiden Zeilen und beiden Spalten verwende:
m[np.ix_([0, 2], [1, 2])]
# array([[2, 3], [8, 9]])
Wenn du zuerst die Zeilen und dann die Spalten auswählst, ergibt m[[0, 2]][:, [1, 2]] denselben Block.
Lesen und Zuweisen verhalten sich unterschiedlich
Fancy Indexing und boolesches Filtern geben Kopien zurück. Wenn c = a[[0, 1]] gilt, lässt eine Änderung an c[0] das Array a unverändert. Aber a[[0, 1]] = -1 schreibt direkt in diese ursprünglichen Positionen. Eine gespeicherte Auswahl und eine Zuweisung über einen Index sind unterschiedliche Operationen.
Das erklärt auch, warum verkettete Änderungen die Quelle möglicherweise nicht erreichen. In a[[0, 1]][0] = -1 ist die erste Auswahl bereits eine temporäre Kopie. Der letzte Schreibvorgang ändert dieses temporäre Array, nicht a.
Gemeinsame Speichernutzung direkt prüfen
np.shares_memory(x, y) prüft, ob sich zwei Arrays im Speicher überlappen. Die Funktion gibt für einen gewöhnlichen, nicht leeren Slice wahr und für eine durch Fancy Indexing erzeugte Kopie falsch zurück. Das Attribut base kann den Eigentümer des zugrunde liegenden Speichers angeben, muss aber nicht das Array bezeichnen, aus dem du zuletzt einen Slice ausgewählt hast. Wenn a = np.arange(6), b = a[2:5] und c = b[0:2] gilt, ist c.base is a wahr und c.base is b falsch. Verwende shares_memory, wenn es darum geht, ob zwei Arrays Daten gemeinsam nutzen.
Wichtige Erkenntnisse
- Eine Zuweisung erzeugt einen weiteren Namen für ein Array; ein einfacher Slice teilt dessen Daten.
- Verwende
.copy()für eine unabhängige Auswahl. - Fancy Indexing erhält die angeforderte Reihenfolge und erlaubt Wiederholungen.
- Zwei Ganzzahllisten als Index bilden Koordinatenpaare;
np.ix_wählt alle Kombinationen aus. - Das Lesen mit Fancy Indexing erzeugt Kopien, direkte indizierte Zuweisungen aktualisieren dagegen die Quelle.
- Prüfe mit
np.shares_memory, ob Arrays Speicher gemeinsam nutzen.
2.3 Mit booleschen Masken und np.where nach Bedingungen filtern
Eine boolesche Maske hält fest, welche Werte eine Bedingung erfüllen. Sobald eine Maske vorliegt, können dieselben Wahrheitswerte Werte auswählen, Ereignisse zählen oder Ersatzwerte bestimmen.
Eine Maske erstellen und anwenden
t = np.array([18.5, 22.0, 15.2, 25.8, 21.1])
warm = t > 20
t[warm]
# array([22. , 25.8, 21.1])
Der Vergleich ergibt [False True False True True]. Die boolesche Indizierung behält die Positionen mit dem Wert wahr und gibt eine Kopie zurück. Eine 1-dimensionale Maske, die auf eine Achse angewendet wird, muss dieselbe Länge wie diese Achse haben.
Um Bedingungen zu verknüpfen, verwende & für und, | für oder und ~ für nicht. Setze jeden Vergleich in Klammern:
comfortable = (t > 18) & (t < 23)
t[comfortable]
# array([18.5, 22. , 21.1])
Pythons and und or versuchen, aus einem ganzen Array einen einzigen Wahrheitswert zu gewinnen, und scheitern bei Arrays mit mehreren Elementen. Lässt du die Klammern weg, ändert sich ebenfalls, wie Python den Ausdruck gruppiert, weil bitweise Operatoren vor Vergleichen ausgewertet werden.
Bedingungen zählen, Anteile berechnen oder Bedingungen prüfen
True zählt als 1 und False als 0. warm.sum() ist 3 und warm.mean() ist 0,6, der Anteil der Tage über 20 °C. np.count_nonzero(warm) zählt ebenfalls wahre Einträge. warm.any() prüft, ob mindestens ein Tag warm ist; warm.all() prüft, ob jeder Tag warm ist.
Diese Operationen beantworten andere Fragen als t[warm].mean(), das die durchschnittliche Temperatur an warmen Tagen berechnet. Der Mittelwert einer Maske misst einen Anteil; der Mittelwert ausgewählter Messwerte behält die Einheit der Messung.
Werte ersetzen oder zwischen Alternativen wählen
Eine Zuweisung über eine Maske aktualisiert die ausgewählten Positionen. Mit t2 = t.copy() hebt die Zeile t2[t2 < 16] = 16 niedrige Messwerte auf 16 an. np.clip(t, 16, 25) gibt ein neues, an beiden Enden begrenztes Array zurück: [18.5 22. 16. 25. 21.1].
np.where(condition, x, y) erstellt ein neues Ergebnis, das an wahren Positionen x und an falschen Positionen y übernimmt. np.where(t > 20, 'warm', 'cool') liefert an jeder ursprünglichen Position eine Bezeichnung. Filtern verkürzt dagegen das Ergebnis. Mit einer Bedingung allein gibt np.where(t > 20) ein Tupel aus Index-Arrays zurück, hier (array([1, 3, 4]),).
Werte oder vollständige Datensätze behalten
Eine Maske derselben Form extrahiert aus einem 2-dimensionalen Array passende Elemente in einen flachen Vektor. Bei m[m > 5] geht die Zeilenstruktur verloren. Um ganze Datensätze zu erhalten, leite aus einer Spalte pro Zeile einen Wahrheitswert ab:
scores = np.array([[78, 85, 92], [64, 70, 58],
[88, 91, 95], [72, 68, 80]])
scores[scores[:, 2] >= 90]
# array([[78, 85, 92], [88, 91, 95]])
Fehlende Werte ausdrücklich finden
NaN ist selbst zu sich selbst nicht gleich. Gleichheits- und Ordnungsvergleiche mit NaN sind falsch; der Ungleichheitsvergleich ist wahr. Daher erkennen weder x == np.nan noch x != np.nan vorhandene und fehlende Einträge korrekt. np.isnan(x) markiert fehlende Positionen, und x[~np.isnan(x)] behält vorhandene Werte.
Wichtige Erkenntnisse
- Eine Maske enthält einen Wahrheitswert pro geprüfter Position.
- Verknüpfe Vergleiche mit
&,|und~und setze sie in Klammern. - Die Summe einer Maske zählt Treffer; ihr Mittelwert ergibt deren Anteil.
- Verwende eine Maske mit einem Wert pro Zeile, um ganze Datensätze zu filtern.
np.wherewählt an jeder Position Werte aus.- Verwende
np.isnan, um NaN zu finden.
3Arrays umformen, transponieren und zusammenfügen
Eine zweckmäßige Array-Form zeigt, wie die Daten zusammengehören: Monate innerhalb von Quartalen, Messwerte innerhalb von Datensätzen oder Stapel innerhalb einer größeren Sammlung. Ordne Werte mit reshape neu an, vertausche die Rollen der Achsen mit transpose und füge Achsen der Länge eins hinzu, wenn ein Vektor die Rolle einer Zeile oder Spalte übernehmen soll. Durch Zusammenfügen und Aufteilen lassen sich diese Gruppen kombinieren oder trennen. Dabei wird die Form geprüft, um die beabsichtigte Struktur zu erhalten.
3.1 Die Form eines Arrays ändern und seine Achsen vertauschen
Eine Formänderung verändert, wie Werte auf Achsen gruppiert werden. Umformen, Transponieren und das Hinzufügen einer Achse erfüllen unterschiedliche Aufgaben, auch wenn einige davon dieselbe endgültige Form ergeben.
Umformen, ohne die Elementanzahl zu ändern
a = np.arange(6)
r = a.reshape(2, 3)
# array([[0, 1, 2], [3, 4, 5]])
Standardmäßig wird jeweils eine Zeile gefüllt: Die letzte Achse ändert sich am schnellsten. Das Umformen derselben Werte zu (3, 2) ergibt [[0 1] [2 3] [4 5]]. Das Produkt der neuen Dimensionen muss der ursprünglichen Elementanzahl entsprechen. Zwölf Elemente passen in (3, 4), aber nicht in (5, 3).
Eine Dimension kann -1 sein, sodass NumPy ihre Länge ermittelt. np.arange(12).reshape(-1, 3) ergibt vier Zeilen mit je drei Elementen; reshape(2, -1) ergibt zwei Zeilen mit je sechs Elementen. Zwei unbekannte Dimensionen sind nicht erlaubt, weil sich ihre einzelnen Längen nicht allein aus der Gesamtzahl bestimmen lassen.
Transponieren vertauscht die Achsen
Für r oben ist r.T gleich [[0 3] [1 4] [2 5]] mit der Form (3, 2). Jede frühere Spalte ist nun eine Zeile. Diese Anordnung unterscheidet sich von r.reshape(3, 2), obwohl die Formen der Ergebnisse übereinstimmen.
| Operation | Was mit r geschieht |
|---|---|
r.reshape(3, 2) | Liest Werte zeilenweise und gruppiert sie neu |
r.T | Vertauscht die Rollen von Zeilen und Spalten |
Transponieren ist nützlich, wenn die nächste Operation die umgekehrte Achsenreihenfolge benötigt. Umformen ist nützlich, wenn eine Folge bereits eine sinnvolle Gruppierung hat, etwa Monate, die zu Quartalen zusammengefasst sind.
Das Transponieren eines 1-dimensionalen Arrays erzeugt keine Spalte
v = np.arange(3) hat nur eine Achse, daher hat v.T weiterhin die Form (3,). Füge ausdrücklich eine Achse hinzu:
column = v[:, np.newaxis] # shape (3, 1)
row = v[np.newaxis, :] # shape (1, 3)
Auch v.reshape(-1, 1) und np.expand_dims(v, 1) erzeugen eine Spalte. np.squeeze(column) entfernt deren Achse der Länge eins und gibt die Form (3,) zurück. Das Hinzufügen einer Achse ändert keine Werte, legt aber für spätere Rechnungen fest, wie sie ausgerichtet werden sollen.
Abflachen und gemeinsame Speichernutzung
r.ravel() und r.flatten() geben beide Werte in einem 1-dimensionalen Ergebnis aus. ravel gibt nach Möglichkeit eine Sicht zurück; flatten kopiert immer. reshape(-1) ist eine weitere Möglichkeit, eine 1-dimensionale Anordnung anzufordern, doch ob sie den Speicher gemeinsam nutzt, hängt von der Speicheranordnung der Eingabe ab. Beim Umformen kann eine Kopie nötig sein; beim Transponieren teilt die Array-Sicht die Daten. Verwende .copy(), wenn unabhängiger Speicher benötigt wird.
Monatswerte zu Quartalen gruppieren
Für monthly = np.array([120, 135, 150, 160, 155, 170, 180, 175, 165, 150, 140, 130]) erstellt monthly.reshape(4, 3) vier Quartalszeilen mit jeweils drei Monaten. Das Summieren jeder Zeile mit .sum(axis=1) ergibt [405 485 520 420]. Die erste Summe ist 120 + 135 + 150 = 405. Das Umformen funktioniert, weil die Monate jedes Quartals in der chronologischen Eingabe bereits beieinanderstehen.
Wichtige Erkenntnisse
- Umformen erhält die Elementanzahl und erfolgt standardmäßig zeilenweise.
- Die Länge einer Dimension
-1kann ermittelt werden. - Transponieren vertauscht die Rollen der Achsen und kann sich vom Umformen zur gleichen Form unterscheiden.
- Verwende eine neue Achse, um einen Vektor in eine Zeile oder Spalte umzuwandeln.
flattenkopiert;ravelund Umformen können Daten gemeinsam nutzen.
3.2 Arrays zusammenfügen und aufteilen
Beim Zusammenfügen werden Werte mehrerer Arrays kombiniert. Beim Aufteilen wird ein Array in Teile zerlegt. Entscheide zuerst, ob die Operation eine vorhandene Achse erweitern oder eine neue einführen soll.
Entlang einer vorhandenen Achse verketten
np.concatenate([a, b], axis=0) fügt Vektoren aneinander. Das Zusammenfügen von [1 2] und [3 4 5] ergibt [1 2 3 4 5].
Bei zwei Arrays mit jeweils der Form (2, 3) fügt Achse 0 Zeilen hinzu und ergibt (4, 3). Achse 1 fügt Spalten hinzu und ergibt (2, 6). Nur die Verknüpfungsachse darf sich in der Länge unterscheiden. So lassen sich die Formen (2, 3) und (2, 2) entlang Achse 1 zu (2, 5) zusammenfügen, aber nicht entlang Achse 0, weil ihre Spaltenanzahlen nicht übereinstimmen.
Die Arrays müssen zusammen als Sequenz übergeben werden, etwa als [a, b]. Das Zusammenfügen erstellt ein neues kombiniertes Array und kopiert die Daten der Eingaben.
Entlang einer neuen Achse stapeln
Für p = np.array([1, 2, 3]) und q = np.array([4, 5, 6]):
| Ausdruck | Form | Anordnung |
|---|---|---|
np.concatenate([p, q]) | (6,) | Ein längerer Vektor |
np.stack([p, q]) | (2, 3) | Ein Vektor pro Zeile |
np.stack([p, q], axis=1) | (3, 2) | Ein Vektor pro Spalte |
stack setzt gleiche Eingabeformen voraus und fügt eine Achse hinzu. concatenate erhält die Anzahl der Achsen. Die Hilfsfunktionen bilden gängige Anordnungen ab: vstack([p, q]) erzeugt Zeilen, hstack([p, q]) fügt diese 1-dimensionalen Eingaben aneinander und column_stack([p, q]) erzeugt Spalten. Wegen des Verhaltens von hstack bei 1-dimensionalen Eingaben reicht sein Name allein nicht aus, um eine Tabelle vorherzusagen.
An Grenzen oder nach Anzahl der Teile aufteilen
np.split(np.arange(10), [3, 7]) teilt vor den Positionen 3 und 7 und ergibt [0 1 2], [3 4 5 6] und [7 8 9]. Die Grenzpositionen sind keine Längen der Teile.
Ein ganzzahliges zweites Argument fordert dagegen gleich große Teile an: np.split(x, 3) verlangt drei gleich große Stücke. Zehn Elemente lassen sich nicht in drei Teile mit gleicher ganzzahliger Größe aufteilen, daher wird ein ValueError ausgelöst. np.array_split(np.arange(10), 3) erlaubt unterschiedliche Längen und ergibt 4, 3 und 3. Diese Aufteilungsaufrufe geben eine Sammlung von Arrays zurück, nicht ein einzelnes Array mit einer neuen Stapelachse.
Eine Messtabelle erstellen
h = np.array([1.62, 1.75, 1.80]) # meters
w = np.array([55.0, 72.5, 80.0]) # kilograms
data = np.column_stack([h, w])
Die Form (3, 2) steht für drei Personen mit Körpergröße und Masse in den Spalten. data[:, 1] / data[:, 0] ** 2 berechnet für jede Zeile die Masse geteilt durch das Quadrat der Körpergröße und ergibt ungefähr 21,0, 23,7 und 24,7 kg/m². Entscheidend ist, dass die Personen in beiden Messwert-Arrays in derselben Reihenfolge stehen.
Treffen Eingaben in Stapeln ein, sammle die Stapel-Arrays in einer Python-Liste und rufe concatenate einmal auf. Wird ein wachsendes Array bei jedem Schleifendurchlauf erneut zusammengefügt, werden seine vorhandenen Daten wiederholt kopiert.
Wichtige Erkenntnisse
- Verkettung erweitert eine Achse; Stapeln fügt eine hinzu.
- Beim Verketten müssen die Dimensionen abseits der Verknüpfungsachse übereinstimmen.
- Verwende
column_stack, um passende Vektoren in Tabellenspalten umzuwandeln. - Aufteilungspositionen sind Grenzen; eine ganzzahlige Anzahl fordert gleich große Teile an.
array_spliterlaubt Teile unterschiedlicher Länge.- Sammle Stapel zuerst und füge sie einmal zusammen.
4Schleifen durch vektorisierte Arithmetik, ufuncs und Broadcasting ersetzen
Mit Ausdrücken für ganze Arrays kannst du numerische Aufgaben beschreiben, ohne für jeden Wert eine Python-Schleife zu schreiben. Beginne mit Arithmetik auf entsprechenden Positionen, wende dann die mathematischen Funktionen von NumPy an und kombiniere verschiedene Formen durch Broadcasting. Anhand der Formen erkennst du, welche Werte gepaart und welche wiederholt werden. Umwandlungsregeln, ungültige Eingaben und Divisionswarnungen sind ebenfalls wichtig, wenn ein kurzer Ausdruck viele Berechnungen gleichzeitig ausführt.
4.1 Elementweise rechnen statt Schleifen zu verwenden
Vektorisierung beschreibt eine Berechnung für ganze Arrays. NumPy übernimmt die wiederholte Arbeit an den einzelnen Elementen in kompiliertem Code, sodass der Python-Ausdruck nahe an der beabsichtigten Berechnung bleiben kann.
Eine Schleife in Arithmetik auf entsprechenden Positionen übersetzen
prices = np.array([2.50, 4.00, 1.20])
qty = np.array([3, 1, 5])
line_totals = prices * qty
order_total = line_totals.sum()
Die Produkte sind [7.5 4. 6.] und ihre Summe ist 17,5. Jeder Preis wird mit seiner zugehörigen Menge gepaart. Eine Python-Schleife, die eine Summe aktualisiert, liefert dasselbe Ergebnis, überlässt Python aber die separate Verarbeitung jedes Paares.
Alle arithmetischen Operatoren arbeiten elementweise: +, -, *, /, //, % und **. Ein Skalar wird auf jeden Eintrag angewendet. 10 - np.array([1, 2, 3]) ergibt [9 8 7]; die Reihenfolge der Operanden ist weiterhin wichtig. Zwei Arrays benötigen gleiche Formen oder Formen, die für Broadcasting kompatibel sind.
Elementweise Produkte und Matrixprodukte unterscheiden
* multipliziert entsprechende Einträge. Für A = np.array([[1, 2], [3, 4]]) und B = np.array([[5, 6], [7, 8]]) ergibt A * B den Wert [[5 12] [21 32]]. Die Matrixmultiplikation verwendet @ und würde [[19 22] [43 50]] ergeben. Wähle * für gepaarte Messwerte wie Preis und Menge.
Vergleiche geben ebenfalls eine Antwort pro Position zurück
a == b erzeugt ein boolesches Array. Es prüft nicht, ob zwei Arrays als ganze Objekte gleich sind. Eine if-Anweisung benötigt einen Wahrheitswert, daher schlägt if a == b: bei Ergebnissen mit mehreren Elementen fehl. np.array_equal(a, b) prüft die exakte Gleichheit ganzer Arrays. Für angenäherte Dezimalzahlen prüft np.allclose(a, b) die Übereinstimmung innerhalb einer Toleranz.
Divisionswarnungen verstehen
Bei den standardmäßigen Fehlereinstellungen von NumPy erzeugt eine Gleitkommadivision durch null eine Warnung und besondere Werte:
np.array([1.0, -1.0, 0.0]) / 0
# array([ inf, -inf, nan])
np.isfinite erkennt Ergebnisse, die weder unendlich noch NaN sind. Eine Ganzzahldivision durch null gibt dagegen ganzzahlige Nullen mit einer Warnung zurück. Diese Nullen erscheinen endlich, prüfe daher ganzzahlige Nenner vor der Ganzzahldivision mit (d == 0).any(). Eine Warnung verdient auch dann Beachtung, wenn das Programm weiterläuft.
Über direkte Aktualisierung entscheiden
a += value verändert den vorhandenen Speicher und behält dessen Datentyp bei. Ist a ein Ganzzahl-Array, löst a += 0.5 einen Umwandlungsfehler aus, weil das Gleitkommaergebnis nach der Umwandlungsregel dieser Operation nicht gespeichert werden kann. a = a + 0.5 erstellt ein Gleitkommaergebnis und bindet a daran. Das unterscheidet sich von der Zuweisung einer einzelnen Dezimalzahl an ein Ganzzahlelement, bei der Nachkommastellen stillschweigend abgeschnitten werden können.
Einen mehrstufigen Ausdruck aufbauen
Für old = np.array([2.50, 4.00, 8.00]) und new = np.array([3.00, 3.00, 8.00]) ergibt (new - old) / old * 100 den Wert [20. -25. 0.]. Bestimme zunächst jede Änderung, dividiere dann durch ihren Ausgangswert und drücke anschließend das Verhältnis als Prozentsatz aus. Die Vorzeichen zeigen einen Anstieg, einen Rückgang und keine Änderung. Für diese Prozentrechnung dürfen die Ausgangswerte nicht null sein.
Wichtige Erkenntnisse
- Vektorisierte Operatoren rechnen auf ganzen Arrays elementweise.
*multipliziert gepaarte Einträge;@berechnet ein Matrixprodukt.- Für den Vergleich ganzer Arrays ist eine Funktion mit einem einzelnen Ergebnis nötig.
- Prüfe Nenner und beachte Divisionswarnungen.
- In-place-Arithmetik behält den Datentyp des Ziels bei.
4.2 Universelle Funktionen auf ganze Arrays anwenden
Eine universelle Funktion, kurz ufunc, wendet eine Berechnung separat auf jede Array-Position an. Diese Funktionen erweitern die Vektorisierung über gewöhnliche Arithmetik hinaus auf Wurzeln, Logarithmen, Rundung, Vergleiche und andere numerische Operationen.
Eine Funktion für Arrays wählen
Unäre ufuncs nehmen eine Eingabe entgegen. np.sqrt(np.array([1, 4, 9])) ergibt [1. 2. 3.], und np.abs(np.array([-2, 3])) ergibt [2 3]. np.exp ist die Exponentialfunktion, np.log der natürliche Logarithmus und np.log10 der Logarithmus zur Basis 10. Beispielsweise ist np.exp(0) gleich 1,0 und np.log10(1000) gleich 3,0.
Pythons Modul math arbeitet mit einzelnen Zahlen. math.sqrt(np.array([1, 4])) kann nicht beide Wurzeln berechnen und löst einen Typfehler aus. Verwende für numerische Arrays die NumPy-Variante. Auch Operatoren rufen ufuncs auf: a + b entspricht np.add(a, b) und a * b entspricht np.multiply(a, b).
Entsprechende Werte vergleichen oder ein ganzes Array reduzieren
Binäre ufuncs nehmen zwei Eingaben entgegen. np.maximum([1, 5, 3], [4, 2, 6]) ergibt [4 5 6] und wählt an jeder Position den größeren Wert. np.minimum wählt den kleineren, und np.power potenziert entsprechende Basen mit den jeweiligen Exponenten.
np.maximum(x, 0) setzt negative Einträge in einem neuen Ergebnis auf null. Das unterscheidet sich von np.max(x), einer Aggregation, die einen einzelnen größten Wert zurückgibt. Für [1, 5, 3] ergibt max den Wert 5; maximum benötigt eine weitere Eingabe und erhält die elementweise Struktur.
Nach der gewünschten Regel runden
| Funktion | Regel | Ergebnis für −2,5 |
|---|---|---|
np.floor | Abrunden in Richtung minus unendlich | −3,0 |
np.ceil | Aufrunden in Richtung plus unendlich | −2,0 |
np.trunc | In Richtung null | −2,0 |
np.round | Zur nächsten Zahl; genaue Hälften zur geraden Zahl | −2,0 |
np.round(x, 2) rundet auf zwei Nachkommastellen. Genaue Hälften folgen der Regel zur geraden Zahl: np.round([0.5, 1.5, 2.5]) ergibt [0. 2. 2.]. Die binäre Näherung kann Werte beeinflussen, die als Dezimalzahl wie genaue Hälften aussehen. Berücksichtige daher bei der Interpretation angezeigter Dezimalzahlen ihre Gleitkommadarstellung.
Werte außerhalb des Definitionsbereichs prüfen
Bei reellen Gleitkommaeingaben gibt np.sqrt(-1.0) unter den standardmäßigen Fehlereinstellungen NaN mit einer Warnung zurück, während np.log(0.0) minus unendlich mit einer Warnung zurückgibt. Anders als math.sqrt(-1) halten diese Aufrufe normalerweise nicht mit einem Definitionsbereichsfehler an. Prüfe die Eingaben, wenn die mathematische Operation einen eingeschränkten Wertebereich voraussetzt. np.isnan markiert NaN; np.isfinite markiert Werte, die weder NaN noch unendlich sind; np.isclose vergleicht Werte mit einer Toleranz.
Ufuncs zu einer nützlichen Berechnung kombinieren
Berechne für die Koordinaten-Arrays x = np.array([3, 5, 8]) und y = np.array([4, 12, 15]) den Abstand vom Ursprung mit np.sqrt(x ** 2 + y ** 2). Das Quadrieren ergibt [9 25 64] und [16 144 225]; die Addition ergibt [25 169 289]; die Wurzeln sind [5. 13. 17.]. np.hypot(x, y) berechnet diese Abstände direkt.
Wichtige Erkenntnisse
- Ufuncs führen numerische Operationen an jeder Position aus.
- Verwende NumPy-Funktionen für Arrays, auch für Wurzeln und Logarithmen.
maximumvergleicht Positionen;maxreduziert Werte.- Abrunden, Aufrunden, Abschneiden der Nachkommastellen und Runden folgen unterschiedlichen Regeln.
- Prüfe nach ungültigen Operationen mit reellen Zahlen auf NaN und unendliche Werte.
4.3 Arrays unterschiedlicher Form durch Broadcasting kombinieren
Broadcasting ermöglicht Arrays unterschiedlicher Form die Teilnahme an elementweisen Berechnungen. Die ausgerichteten Achsen bestimmen, welche Werte gepaart und welche wiederholt werden.
Dimensionen von rechts vergleichen
Richte Formen an ihren rechten Enden aus. Jedes Paar von Achsenlängen muss gleich sein oder eine Länge von 1 enthalten. Fehlende führende Achsen zählen als Länge 1. Eine Achse der Länge eins wird gedanklich an die andere Länge angepasst; NumPy muss die wiederholten Eingabewerte nicht kopieren.
Bei (4, 3) und (3,) stimmen die letzten Längen mit 3 überein. Die fehlende führende Dimension verhält sich wie 1 und wird auf 4 erweitert. Das Ergebnis ist (4, 3): Der Vektor wird auf jede Zeile angewendet. (4, 3) und (4,) schlagen fehl, weil die letzten Längen 3 und 4 nicht übereinstimmen und keine von beiden 1 ist. Ein inkompatibles Paar löst einen ValueError aus.
Spalten zentrieren oder standardisieren
X = np.array([[1, 10], [2, 20], [3, 30]])
centered = X - X.mean(axis=0)
Die Spaltenmittelwerte sind [2. 20.] mit der Form (2,). Sie passen zur letzten Achse von (3, 2) und ergeben [[-1. -10.] [0. 0.] [1. 10.]]. Die Division des zentrierten Ergebnisses durch X.std(axis=0) standardisiert jede Spalte und ergibt in beiden Spalten ungefähr −1,22, 0 und 1,22. Für diese Division darf die Streuung keiner Spalte null sein.
Eine Achse für Zeilenberechnungen erhalten
Verwende eine Ergebnistabelle mit vier Lernenden und drei Tests:
scores = np.array([[78, 85, 92], [64, 70, 58],
[88, 91, 95], [72, 68, 80]])
scores.mean(axis=1) hat die Form (4,). Diese Form lässt sich nicht als ein Mittelwert pro Zeile durch Broadcasting mit (4, 3) kombinieren. Erhalte die entfernte Achse:
row_mean = scores.mean(axis=1, keepdims=True)
centered = scores - row_mean
row_mean hat nun die Form (4, 1). Die führende 4 passt zu den Zeilen; die abschließende 1 wird über drei Spalten erweitert. scores.mean(axis=1)[:, np.newaxis] erzeugt dieselbe Form. Für die Zeile [78, 85, 92] ergibt die Subtraktion ihres Mittelwerts 85 den Wert [-7. 0. 7.].
Mit derselben Regel eine Tabelle erstellen
np.arange(1, 4)[:, np.newaxis] * np.arange(1, 5) kombiniert (3, 1) und (4,). Beide Arrays werden auf die Ergebnisform (3, 4) erweitert und ergeben [[1 2 3 4] [2 4 6 8] [3 6 9 12]].
Eine Erweiterung kann auch unbeabsichtigt sein. Eine Spalte der Form (3, 1) minus ein Vektor der Form (3,) erzeugt alle neun paarweisen Differenzen mit der Form (3, 3). Wenn du drei entsprechende Differenzen beabsichtigt hast, bringe beide Eingaben auf die Form (3,), zum Beispiel mit column.ravel().
Jede Spalte vor dem Addieren gewichten
Für dieselbe Ergebnistabelle und w = np.array([0.2, 0.3, 0.5]) wendet scores * w die drei Gewichte auf jede Zeile an. Das Summieren mit .sum(axis=1) ergibt [87.1 62.8 92.4 74.8]. Das erste Ergebnis ist 15,6 + 25,5 + 46,0 = 87,1.
Wichtige Erkenntnisse
- Richte Formen von rechts aus; gepaarte Längen müssen übereinstimmen oder 1 enthalten.
- Eine Achse der Länge eins steuert die Richtung der Erweiterung.
- Spaltenaggregationen passen üblicherweise direkt zu einer Tabelle.
- Erhalte Zeilenaggregationen mit
keepdims=Truein Spaltenform. - Broadcasting kann eine unbeabsichtigte Tabelle paarweiser Ergebnisse erzeugen.
- Gewichte Spalten, bevor du jede Zeile reduzierst.
5Arrays durch Aggregation entlang ihrer Achsen zusammenfassen
Aus einer Tabelle kannst du eine Gesamtsumme, eine Zusammenfassung pro Datensatz oder eine Zusammenfassung pro Variable gewinnen. Entscheide, welche Achse zusammengefasst werden soll, und wähle dann einen Kennwert, der deine Frage beantwortet. Positionen, kumulative Summen und Rangplätze bieten unterschiedliche Sichten auf die Daten. Fehlende Werte und Bedingungen erfordern eigene Entscheidungen, weil Filtern oder Auffüllen sowohl die einbezogenen Beobachtungen als auch die Bedeutung des Ergebnisses verändern kann.
5.1 Ein ganzes Array oder entlang einer Achse aggregieren
Eine Aggregation fasst Werte zu weniger Ergebnissen zusammen: einer Summe, einem Mittelwert, einem Extremwert oder einem Streuungsmaß. Die Wahl der Achse gehört zur Wahl der Fragestellung, denn sie bestimmt, welche Wertegruppen zusammengefasst werden.
Die angegebene Achse zusammenfassen
Bei einer Tabelle der Form (4, 3) mit vier Lernenden und drei Tests berücksichtigt eine Aggregation ohne axis alle 12 Werte. scores.sum() ergibt eine Gesamtsumme. scores.mean(axis=0) fasst die Achse der Lernenden zusammen und lässt drei Testmittelwerte übrig. scores.mean(axis=1) fasst die Testachse zusammen und lässt vier Mittelwerte der Lernenden übrig.
scores = np.array([[78, 85, 92], [64, 70, 58],
[88, 91, 95], [72, 68, 80]])
Die Gesamtsumme ist 941. Die Spaltenmittelwerte sind [75.5 78.5 81.25]; die Zeilenmittelwerte sind ungefähr [85. 64. 91.33 73.33]. Frag dich, welche Achse verschwinden soll. Die Aussage „Achse 0 bedeutet jede Zeile“ kehrt die Operation um: Achse 0 fasst Zeilen zusammen.
Die zurückzugebende Größe wählen
| Operation | Ergebnistyp |
|---|---|
sum, prod | Summe oder Produkt |
mean | Arithmetisches Mittel |
min, max | Extremwert |
argmin, argmax | Position eines Extremwerts |
std, var | Standardabweichung oder Varianz |
Methoden wie a.sum() und Funktionen wie np.sum(a) beschreiben dieselbe grundlegende Operation. Die NumPy-Methoden vermeiden das abweichende Verhalten der eingebauten Python-Funktionen. Beispielsweise addiert Pythons sum(scores) Zeilen-Arrays zu Spaltensummen, während scores.sum() alle Einträge zusammenfasst. Pythons max(scores) versucht, Zeilen zu vergleichen, und löst einen Fehler wegen eines mehrdeutigen Wahrheitswerts aus.
Positionen unterscheiden sich von Werten
scores.mean(axis=1).argmax() ist 2: Die dritte Person hat den höchsten Mittelwert. argmax gibt bei gleichen Maxima die erste Position zurück. Ohne Achse gibt es bei einer Tabelle einen zeilenweise abgeflachten Index zurück; scores.argmax() ist 8. np.unravel_index(8, scores.shape) stellt die Koordinate (2, 2) wieder her.
Verwende keepdims=True, wenn eine Aggregation zur ursprünglichen Tabelle passen muss. scores.sum(axis=1, keepdims=True) hat die Form (4, 1) und eignet sich damit für einen Normierungswert pro Zeile. Ohne diese Angabe hat das Ergebnis die Form (4,).
Zwischensummen erhalten, wenn die Reihenfolge wichtig ist
np.cumsum([3, 1, 4, 1, 5]) ergibt [3 4 8 9 14]. Jede Position enthält die Summe bis zu diesem Punkt. np.cumprod([1, 2, 3, 4]) ergibt entsprechend [1 2 6 24]. np.diff([3, 1, 4, 1, 5]) ergibt die vier Änderungen zwischen benachbarten Werten [-2 3 -3 4]. Gib bei einer Tabelle axis=1 an, um separate kumulative Summen entlang der Zeilen zu erhalten.
Die Konvention für die Streuung angeben
std und var dividieren die Summe der quadrierten Abweichungen standardmäßig durch die Anzahl der Werte: ddof=0. Verwende ddof=1 für die Stichprobenformel, deren Divisor um eins kleiner ist. Für [2, 4, 4, 4, 5, 5, 7, 9] ist der Mittelwert 5, die standardmäßige Standardabweichung 2,0 und die Stichprobenstandardabweichung etwa 2,14. Ein Bericht sollte deutlich machen, welche Konvention er verwendet.
Wichtige Erkenntnisse
- Das Argument
axisbezeichnet die Achse, die zusammengefasst wird. - Ohne Achsenangabe entsteht eine Zusammenfassung für das ganze Array.
argminundargmaxgeben Positionen zurück, bei gleichen Extremwerten die erste.keepdims=Trueerhält reduzierte Achsen mit der Länge 1.- Kumulative Funktionen erhalten Zwischenergebnisse.
- NumPy verwendet standardmäßig
ddof=0;ddof=1wählt den Divisor für die Stichprobe. - Bevorzuge bei Arrays NumPy-Aggregationen gegenüber eingebauten Python-Funktionen.
5.2 Mediane, Perzentile, Sortierung und unterschiedliche Werte nutzen
Rangbasierte Kennwerte beschreiben, wo Werte in einer sortierten Verteilung liegen. Sortieren hilft auch dabei, Datensätzen Ränge zuzuweisen. Bei einer Tabelle musst du jedoch sorgfältig vorgehen, damit die Felder jedes Datensatzes zusammenbleiben.
Die Mitte und die Quartile bestimmen
Für x = np.array([12, 15, 11, 20, 18, 14]) lautet die sortierte Reihenfolge [11 12 14 15 18 20]. Bei sechs Werten bildet np.median(x) das arithmetische Mittel der beiden Werte in der Mitte, 14 und 15, und ergibt 14,5. Bei einer ungeraden Anzahl ist der Median der einzelne Wert in der Mitte.
np.percentile(x, q) erwartet einen Prozentsatz von 0 bis 100. np.quantile(x, q) erwartet den entsprechenden Anteil von 0 bis 1. Ihre standardmäßige lineare Interpolation kann einen Wert zwischen Beobachtungen ergeben. Bei sechs Werten liegt das 25. Perzentil an der von null aus gezählten Position 0,25 × 5 = 1,25. Diese liegt ein Viertel des Weges von 12 zu 14 und ergibt 12,5. Das 50. und das 75. Perzentil sind 14,5 und 17,25, der Interquartilsabstand ist also 4,75.
Der Median ist gegenüber einem Extremwert robuster als das arithmetische Mittel. Wird 200 zu diesen Daten hinzugefügt, steigt das arithmetische Mittel von 15,0 auf etwa 41,4; der Median steigt von 14,5 auf 15,0. Keines der beiden Maße allein beschreibt die ganze Verteilung.
Sortierte Daten oder Sortierpositionen wählen
np.sort(x) gibt eine sortierte Kopie zurück. x.sort() verändert x und gibt None zurück, sodass y = x.sort() keine sortierten Werte in y ablegt. Für absteigende Werte verwende np.sort(x)[::-1].
Bei einem 2-dimensionalen Array wird standardmäßig entlang der letzten Achse sortiert, also jede Zeile unabhängig. axis=0 sortiert jede Spalte unabhängig. Keine der beiden Operationen sortiert Datensätze. Für tab = np.array([[3, 1], [1, 2], [2, 0]]) ergibt np.sort(tab, axis=0) den Wert [[1 0] [2 1] [3 2]] und trennt damit Werte, die ursprünglich zusammengehörten.
Um Datensätze zu erhalten, ermittle eine Reihenfolge aus der Schlüsselspalte und wende sie auf ganze Zeilen an:
order = tab[:, 0].argsort()
ranked = tab[order]
# array([[1, 2], [2, 0], [3, 1]])
Dieselbe Indexreihenfolge kann zusammengehörige Vektoren neu anordnen. Wenn avg = np.array([85.0, 64.0, 91.33, 73.33]) und names = np.array(['Ana', 'Ben', 'Chen', 'Dara']) gilt, ordnet order = np.argsort(avg)[::-1] die Mittelwerte absteigend. names[order] ergibt ['Chen' 'Ana' 'Dara' 'Ben'].
Unterschiedliche Werte zählen und Zugehörigkeit prüfen
np.unique gibt sortierte unterschiedliche Werte zurück. Mit return_counts=True gibt es auch die zugehörigen Häufigkeiten zurück:
colors = np.array(['red', 'blue', 'red', 'green', 'blue', 'red'])
values, counts = np.unique(colors, return_counts=True)
Die Ausgaben sind ['blue' 'green' 'red'] und [2 1 3]. values[counts.argmax()] findet den häufigsten Wert, 'red'. Die Positionen der Häufigkeiten entsprechen denen der unterschiedlichen Werte.
np.isin(a, allowed) gibt eine Maske für die Zugehörigkeit zu einer Sammlung zurück. Für a = np.arange(1, 6) ergibt np.isin(a, [2, 4]) den Wert [False True False True False]. Damit lassen sich diese Werte oder die zugehörigen Datensätze auswählen.
Wichtige Erkenntnisse
- Der Median beruht auf der Position in der sortierten Reihenfolge und ist robust gegenüber Extremwerten.
- Perzentile verwenden 0 bis 100; Quantile verwenden 0 bis 1.
- Die standardmäßige Perzentilinterpolation kann zwischen Beobachtungen liegen.
np.sortkopiert;.sort()eines Arrays verändert es und gibtNonezurück.- Nutze
argsort-Positionen, damit Datensätze und zugehörige Arrays ausgerichtet bleiben. unique(..., return_counts=True)ordnet unterschiedlichen Werten ihre Häufigkeiten zu.isinerstellt eine Zugehörigkeitsmaske.
5.3 Daten unter Berücksichtigung fehlender Werte und Bedingungen zusammenfassen
Für fehlende Daten und gefilterte Teilmengen brauchst du eine ausdrückliche Regel zur Zusammenfassung. Ein numerisches Ergebnis kann falsch sein, selbst wenn die Array-Operation erfolgreich ausgeführt wird: Ein Platzhalter kann als Messwert gezählt oder eine leere Teilmenge für einen aussagekräftigen Mittelwert gehalten werden.
Fehlende Werte vor dem Zusammenfassen finden
NaN wird bei gewöhnlichen Summen und Mittelwerten weitergegeben. Für x = np.array([3.0, np.nan, 5.0]) ergeben sowohl x.sum() als auch x.mean() den Wert NaN. np.nansum(x) ergibt 8,0 und np.nanmean(x) ergibt 4,0; die fehlende Position wird übersprungen. Verwandte Funktionen sind nanmax, nanmin, nanstd und nanmedian. Sind alle Werte fehlend, gibt nanmean NaN mit einer Warnung zurück, weil keine beobachteten Werte übrig bleiben.
Für Sensormesswerte in °C:
r = np.array([21.5, np.nan, 22.1, 23.0, np.nan, 21.9])
missing = np.isnan(r)
missing.sum() ist 2, missing.mean() ist etwa 0,33, und r[~missing] behält vier Messwerte. np.nanmean(r) ist 22,125 und berücksichtigt nur diese vier Werte. Der Vergleich r == np.nan würde die fehlenden Messwerte nicht markieren.
Platzhaltercodes zuerst umwandeln
Eine Zahl wie −999 kann in einem Eingabesystem fehlende Daten darstellen. NumPy behandelt sie als echten Messwert, bis du sie ersetzt:
v = np.array([12, -999, 15, -999, 9]).astype(float)
v[v == -999] = np.nan
np.nanmean(v) # 12.0
Wandle zuerst in Gleitkommazahlen um, weil ein Ganzzahl-Array NaN nicht speichern kann. Diese Ersetzung ist nur angebracht, wenn −999 für diese Daten als Fehlwertcode definiert ist.
Auffüllen verändert die Verteilung
Werden fehlende Temperaturen durch null ersetzt, beträgt der Mittelwert des Beispiels 14,75, obwohl keine Temperatur von null gemessen wurde. Das Auffüllen mit dem Mittelwert der beobachteten Werte, 22,125, erhält diesen Mittelwert, verringert aber die scheinbare Streuung. Ein aufgefüllter Wert ist eine eingefügte Schätzung; seine Auswirkung gehört daher zur Entscheidung über die Analyse.
Für eine 2-dimensionale Tabelle D fasst np.nanmean(D, axis=0) die beobachteten Werte jeder Spalte zusammen. Jede Spalte kann eine andere Anzahl haben. Um Zeilen mit einem oder mehreren fehlenden Werten zu entfernen:
complete = ~np.isnan(D).any(axis=1)
clean_rows = D[complete]
Die Reduktion erzeugt eine Entscheidung pro Zeile; die Negation behält Zeilen ohne fehlende Einträge. Mit D = np.array([[1., 2.], [np.nan, 4.], [5., np.nan], [7., 8.]]) bleiben so [[1. 2.] [7. 8.]] erhalten.
Eine Bedingung oder Gruppe zusammenfassen
Für Temperaturen t berechnet t[t > 20].mean() nur den Mittelwert der Tage über 20 °C. Verwende bei gruppierten Daten eine passende Bezeichnungsmaske: Mit group = np.array(['A', 'B', 'A', 'B', 'A']) und value = np.array([10, 20, 14, 26, 12]) ist value[group == 'A'].mean() gleich 12,0 und der entsprechende Mittelwert von B gleich 23,0. Durchlaufe np.unique(group), um dies für jede Gruppe zu wiederholen.
Prüfe mask.any(), bevor du eine gefilterte Teilmenge zusammenfasst. Der Mittelwert einer leeren Auswahl ist NaN mit einer Warnung, ihre Summe dagegen 0. Diese null kann eine sinnvolle leere Summe sein, belegt aber nicht, dass ein Messwert vorhanden war.
Wichtige Erkenntnisse
- Gewöhnliche Summen und Mittelwerte geben NaN weiter; Varianten für NaN überspringen es.
- Wandle definierte Fehlwertcodes bei Gleitkommaspeicherung in NaN um.
- Das Auffüllen fehlender Werte verändert die Kennwerte.
- Zeilenweise Fehlwertprüfungen können vollständige Datensätze erkennen.
- Kombiniere Bezeichnungs- oder Bedingungsmasken mit Aggregationen.
- Prüfe vor der Interpretation des Mittelwerts, ob eine Teilmenge leer ist.
6Zufallszahlen erzeugen und Simulationen durchführen
Zufallsarrays ermöglichen wiederholbare Stichproben und praktische Experimente. Erstelle einen Generator mit Startwert, wähle eine Verteilung und eine Ausgabeform und erhalte beim Mischen oder Aufteilen von Daten die Beziehungen innerhalb der Datensätze. Lege bei einer Simulation den Aufbau der Versuchsdurchläufe ausdrücklich fest, bevor du Ereignisse oder Positionen im Verlauf berechnest. Vergleiche Ergebnisse mit einfachen exakten Fällen und unterscheide gewöhnliche Stichprobenschwankungen von Fehlern im Code.
6.1 Mit einem Generator reproduzierbare Zufallsstichproben ziehen
Ein Zufallszahlengenerator unterstützt Stichproben, das Mischen und Simulationen. Ein Startwert macht den Anfangszustand wiederholbar, sodass du eine Analyse erneut ausführen kannst, während du ihre Logik untersuchst.
Einen Generator erstellen und wiederverwenden
rng = np.random.default_rng(42)
NumPy empfiehlt diese Generator-Schnittstelle für neuen Code. Ihr standardmäßiger Bitgenerator ist PCG64. Ohne Startwert bezieht default_rng() neue Entropie aus dem Betriebssystem. Ältere Aufrufe wie np.random.seed und np.random.rand verwenden einen gemeinsamen globalen Zustand; Generator-Objekte ermöglichen einer Analyse, ihren eigenen Zustand direkt zu verwalten.
Pseudozufallswerte stammen aus einem deterministischen Algorithmus. Derselbe Anfangszustand und dieselbe Folge von Aufrufen reproduzieren die Zahlenfolge in derselben Umgebung. Jede Ziehung verändert den Zustand. Wird bei jedem Schleifendurchlauf ein neuer Generator mit dem Startwert 42 erstellt, beginnt die Folge erneut und wiederholt dieselben anfänglichen Ziehungen, statt sie fortzusetzen. Halte neben dem Startwert auch die NumPy-Version und den Code fest, denn die Kompatibilität der Folge zwischen Versionen oder allen Umgebungen ist nicht garantiert. Verwende für Passwörter oder Sicherheitstoken Pythons Modul secrets.
Eine Verteilung und eine Ausgabeform wählen
| Aufruf | Bedeutung |
|---|---|
rng.random(5) | Fünf Dezimalzahlen ab 0 einschließlich bis 1 ausschließlich |
rng.uniform(2, 8, size=5) | Fünf Ziehungen aus der Gleichverteilung über das Intervall von 2 bis 8 |
rng.integers(1, 7, size=10) | Zehn Ganzzahlen von 1 bis einschließlich 6 |
rng.normal(loc=170, scale=10, size=(3, 4)) | Eine 3 × 4 Stichprobe aus einer Normalverteilung |
size kann eine Elementanzahl oder ein Formtupel sein. Bei normal ist loc der Mittelwert der Verteilung und scale ihre Standardabweichung. Eine Varianz von 100 benötigt daher scale=10. Der tatsächliche Mittelwert und die Standardabweichung einer kleinen Stichprobe müssen nicht exakt mit den Verteilungsparametern übereinstimmen.
Bei ganzzahligen Ziehungen ist die obere Schranke standardmäßig ausgeschlossen. Für einen Würfel brauchst du integers(1, 7), da integers(1, 6) keine 6 ziehen kann. integers(1, 6, endpoint=True) schließt die obere Schranke ein und modelliert ebenfalls einen Würfel.
Werte mit oder ohne Zurücklegen ziehen
rng.choice(['heads', 'tails'], size=5) führt fünf Ziehungen mit Zurücklegen aus. Ein Wert kann mehrfach erscheinen. Für unterschiedliche gezogene Positionen verwende replace=False; werden mehr Positionen angefordert, als die Grundgesamtheit enthält, wird ein ValueError ausgelöst. Wahrscheinlichkeiten können als p=[0.7, 0.3] in derselben Reihenfolge wie die Werte angegeben werden und müssen sich zu 1 summieren.
Ziehen ohne Zurücklegen verhindert, dass eine Eingabeposition zweimal ausgewählt wird. Enthält die Eingabe selbst doppelte Werte, können dennoch gleiche Werte in der Stichprobe erscheinen.
Datensätze mischen, ohne ihre Felder zu trennen
rng.shuffle(a) ordnet das vorhandene Array neu und gibt None zurück. rng.permutation(a) gibt eine gemischte Kopie zurück. rng.permutation(10) ergibt die Ganzzahlen 0 bis einschließlich 9 in zufälliger Reihenfolge, die sich als Zeilenindizes eignen.
Bei einem 2-dimensionalen Array ist die Standardachse 0: Ganze Zeilen werden zusammen verschoben. So bleiben die Felder jeder Beobachtung aufeinander ausgerichtet. Um zwei zusammengehörige Arrays einheitlich zu mischen, erzeuge eine Permutation ihrer gemeinsamen Datensatzindizes und wende sie auf beide an.
Wichtige Erkenntnisse
- Erstelle einen Generator mit Startwert einmal und verwende seinen fortgeschriebenen Zustand erneut.
- Reproduzierbarkeit hängt vom Startwert, den Aufrufen und der numerischen Umgebung ab.
- Ganzzahlige Ziehungen schließen die obere Schranke aus, sofern nicht
endpoint=Truegesetzt ist. - Bei der Normalverteilung ist
scaledie Standardabweichung, nicht die Varianz. choicezieht standardmäßig mit Zurücklegen.shuffleverändert das Array;permutationgibt ein gemischtes Ergebnis zurück.
6.2 Vektorisierte Simulationen durchführen
Eine vektorisierte Simulation stellt wiederholte Versuchsdurchläufe als Arrays dar, wendet die Ereignisregel auf diese Arrays an und fasst die Ergebnisse zusammen. Die Form des Arrays sollte zeigen, was ein Versuchsdurchlauf enthält.
Ein Ereignis in einen Anteil umwandeln
rng = np.random.default_rng(42)
rolls = rng.integers(1, 7, size=100_000)
estimate = (rolls == 6).mean()
Die Maske ist für jede beobachtete 6 einmal wahr. Ihr Mittelwert schätzt die Wahrscheinlichkeit dieses Ereignisses, nahe 1/6 beziehungsweise etwa 0,1667. rolls.mean() beantwortet eine andere Frage: die durchschnittliche Augenzahl, nahe 3,5. Ein fester Startwert wiederholt eine Schätzung, macht sie aber nicht exakt.
Vektorisierung vermeidet Arbeit auf Python-Ebene für jede Ziehung und macht große Simulationen oft deutlich schneller als eine Schleife. Die Beschleunigung hängt von der Berechnung, der Array-Größe und dem Computer ab und ist daher keine feste Eigenschaft des Ereignisses.
Eine Zeile pro Versuchsdurchlauf mit mehreren Werten verwenden
Um in jedem Versuchsdurchlauf zwei Würfel zu simulieren:
dice = rng.integers(1, 7, size=(100_000, 2))
totals = dice.sum(axis=1)
p_seven = (totals == 7).mean()
Die Tabelle hat 100.000 Zeilen für Versuchsdurchläufe und zwei Würfelspalten. Das Reduzieren von Achse 1 ergibt eine Summe pro Versuchsdurchlauf. Sechs der 36 gleich wahrscheinlichen geordneten Paare ergeben die Summe 7, daher sollte die geschätzte Wahrscheinlichkeit nahe 6/36 liegen. Das Reduzieren von Achse 0 würde dagegen zwei Summen über alle Versuchsdurchläufe ergeben und das Ereignis auf Ebene der einzelnen Durchläufe verlieren.
Auch größere Simulationen schwanken
Für unabhängige Versuchsdurchläufe ist der Standardfehler eines geschätzten Anteils:
Dabei ist die Ereigniswahrscheinlichkeit und die Anzahl der Versuchsdurchläufe. Für eine gewürfelte 6 bei 100.000 Durchläufen beträgt er etwa 0,0012. Nach einer Normalapproximation liegen etwa 95 % der Schätzungen höchstens 0,0023 von 1/6 entfernt. Eine Erhöhung der Anzahl der Versuchsdurchläufe um den Faktor 100 verringert den Standardfehler um den Faktor 10. Mehr Ziehungen korrigieren kein falsch programmiertes Ereignis.
Eine Zufallsbewegung erstellen und untersuchen
steps = rng.choice([-1, 1], size=1000) zieht Schritte nach links oder rechts. walk = steps.cumsum() ergibt die Position nach jedem Schritt. Maximum und Minimum geben die äußersten erreichten Positionen an. Um den ersten Punkt zu finden, der mindestens 10 Einheiten vom Start entfernt ist:
hit = np.abs(walk) >= 10
if hit.any():
step_count = hit.argmax() + 1
argmax findet den ersten wahren Eintrag, gibt aber auch 0 zurück, wenn alle Einträge falsch sind. Die Prüfung mit any() unterscheidet einen tatsächlichen Treffer von keinem Treffer. Addiere 1, weil die Array-Position 0 die Position nach Schritt 1 ist.
Für viele Zufallsbewegungen summiert rng.choice([-1, 1], size=(5000, 1000)).cumsum(axis=1) jede Zeile separat. walks[:, -1] wählt alle Endpositionen aus; ihr Mittelwert liegt nahe 0 und ihre Standardabweichung nahe der Quadratwurzel aus 1.000, also etwa 31,6.
Permutationen und exakte Prüfungen nutzen
Für eine zufällige Aufteilung von 100 Datensätzen kannst du idx = rng.permutation(100) und dann data[idx[:80]] und data[idx[80:]] verwenden. Die beiden disjunkten Slices einer Permutation ordnen jeden Datensatz genau einmal zu. Vergleiche bei einer Simulation einen einfachen Fall mit einer exakten Antwort, etwa dem Würfelmittelwert 3,5, bevor du komplizierteren Ausgaben vertraust.
Wichtige Erkenntnisse
- Stelle einen Versuchsdurchlauf in der Array-Form eindeutig dar.
- Ein Mittelwert boolescher Werte schätzt eine Ereigniswahrscheinlichkeit.
- Reduziere innerhalb der Versuchsdurchläufe, bevor du Ergebnisse über die Durchläufe hinweg kombinierst.
- Der Standardfehler nimmt mit der Quadratwurzel der Anzahl der Versuchsdurchläufe ab.
- Prüfe, ob ein Treffer vorliegt, bevor du mit
argmaxden ersten Treffer suchst. - Eine Permutation kann disjunkte zufällige Aufteilungen von Datensätzen erzeugen.
- Prüfe die Simulationslogik anhand eines einfachen Falls mit exakter Lösung.
NumPy-Arrays: Beispiele
1Ein verlässliches Messwert-Array erstellen
14 Schritte
- 1EinführungDatensätze und Messungen planen
Vor jeder Berechnung sind für eine Messtabelle zwei Entscheidungen nötig: was jede Achse darstellt und welche Art von Werten gespeichert werden muss. Wir erstellen eine kleine Tabelle, prüfen ihre Form und wählen Erzeugungs- und Umwandlungsmethoden, die die Daten erhalten.
Belasse
import numpy as npam Anfang des Skripts. Der Namenpermöglicht den Zugriff auf die NumPy-Funktionen, die in den Beispielen verwendet werden. - 2ErklärungEine Tabelle anhand ihrer Achsen lesen
Erstelle
a = np.array([[2, 4, 6], [3, 5, 7]]). Die äußere Sequenz liefert zwei Zeilen; jede innere Sequenz liefert drei Werte.a.shapeist(2, 3),a.ndimist 2 unda.sizeist 6. Die Form beschreibt die Anordnung, ndim zählt die Achsen und size zählt alle Einträge. Wenn jede Zeile ein Datensatz ist, enthält diese Tabelle zwei Datensätze mit je drei Messwerten. - 3KernaussageGleiche Größen können unterschiedliche Strukturen haben
Ein Vektor der Länge sechs hat die Form
(6,). Eine Tabelle mit einer Zeile hat die Form(1, 6)und eine Tabelle mit einer Spalte die Form(6, 1). Jede enthält sechs Werte, aber nur die letzten beiden haben separate Zeilen- und Spaltenachsen.Das abschließende Komma in
(6,)kennzeichnet ein Tupel mit einem Eintrag. Das ist eine nützliche Information: Der Vektor hat eine Achse und damit keine separate Zeilenrichtung, die sich zu einer Spalte transponieren ließe. - 4HerausforderungDie Multiplikation vor der Ausführung vorhersagen
Welche Ergebnisse liefern
[2, 5] * 2undnp.array([2, 5]) * 2?---reveal---
Die Liste wird zu
[2, 5, 2, 5]. Das Array wird zu[4 10]. Listen wiederholen bei der Multiplikation mit einer Ganzzahl ihren Inhalt; numerische Arrays multiplizieren die Werte an jeder Position. Das Array behält seine Form und eignet sich daher, um eine Berechnung auf jeden erfassten Wert anzuwenden. - 5BeispielEine Tabelle mit bekannter Form reservieren
Angenommen, zwei Stationen liefern jeweils vier Niederschlagsmesswerte in Millimetern. Erstelle
rain = np.zeros((2, 4))und weise dannrain[0] = [4.0, 0.0, 3.5, 6.0]zu.Das Tupel
(2, 4)ist ein einzelnes Formargument. Zeros verwendet standardmäßig Gleitkommaspeicherung, sodass der Messwert 3,5 erhalten bleibt. Wenn du die endgültige Form einmal reservierst, vermeidest du das wiederholte Kopieren eines wachsenden Arrays beim Eintreffen der Messwerte. - 6TippDie anfängliche Füllung bewusst wählen
Verwende
zeros, wenn anfängliche Nullen sinnvoll sind,onesfür Einsen undfull(shape, value)für einen anderen wiederholten Wert. Ihre Namen beschreiben den anfänglichen Inhalt.emptyreserviert nur Speicher. Seine Anfangswerte sind nicht zur Verwendung bereit, daher muss jeder Eintrag gefüllt werden, bevor er gelesen wird. Eine mit Nullen gefüllte Tabelle lässt sich leichter prüfen, während du Code schreibst, der nur einigen ihrer Einträge Werte zuweist. - 7ErklärungPunkte und Abstände getrennt zählen
Für Messpositionen von 0 m bis einschließlich 2 m in Abständen von 0,5 m gibt es fünf Punkte und vier Abstände.
np.linspace(0, 2, 5)erstellt diese Punkte und schließt beide Endpunkte ein.np.arange(0, 2, 0.5)verwendet eine Schrittweite und schließt den Stoppwert aus, lässt also 2 m weg. Gleitkommarundung kann bei dezimalenarange-Gittern ebenfalls überraschen; verwendelinspace, wenn die Punktanzahl vorgegeben ist. - 8HerausforderungEin Gitter anhand seiner Endpunkte wählen
Ein Scan benötigt neun gleichmäßig verteilte Positionen von 0 cm bis 4 cm einschließlich beider Endpunkte. Welcher Erzeugungsaufruf passt und wie groß ist der Abstand?
---reveal---
Verwende
np.linspace(0, 4, 9). Neun Punkte ergeben acht Abstände über 4 cm, der Abstand beträgt also 0,5 cm. Ein drittes Argument von 8 würde acht Punkte anfordern, sodass nur sieben Abstände blieben und ein anderer Abstand zwischen den Messwerten entstünde. - 9ErklärungDen abgeleiteten Datentyp prüfen
np.array([1, 2.5])wird zu einem Gleitkomma-Array, weil ein gemeinsamer Datentyp beide Werte aufnehmen muss. Das Mischen einer Zahl mit Text kann dagegen alle Werte in Text umwandeln, sodass Rechnungen fehlschlagen.Prüfe
a.dtype, wenn sich die Werte nicht wie erwartet verhalten.a.itemsizegibt den Speicherbedarf in Byte pro Element an; multiplizierst du ihn mita.size, erhältst dua.nbytes, die Gesamtzahl der von den Elementen belegten Byte. - 10BeispielBeobachten, wie eine Zuweisung Nachkommastellen entfernt
Beginne mit
counts = np.array([2, 4, 6])und führe danncounts[0] = 3.8aus. Der erste Eintrag wird zu 3, weil der vorhandene Speicher ganzzahlig bleibt.Um spätere Dezimalzahlen zu erhalten, erstelle zuerst mit
values = counts.astype(float)einen Gleitkommaspeicher.astypeerstellt eine umgewandelte Kopie. Es ändert weder den Datentyp des ursprünglichen Arrays noch stellt es Nachkommainformationen wieder her, die eine frühere Zuweisung bereits entfernt hat. - 11KernaussageUmwandlung und Rundung sind getrennte Schritte
np.array([2.8, -2.8]).astype(int)ergibt[2 -2]: Das Abschneiden der Nachkommastellen erfolgt in Richtung null.np.roundrundet zur nächsten Zahl und genaue Hälften zur geraden Zahl, sodass 2,5 auf 2,0 gerundet wird.Kleine Ganzzahldatentypen bergen ein anderes Risiko. Ein
uint8kann 260 nicht speichern, sodass Array-Arithmetik wie 250 plus 10 durch Überlauf 4 ergeben kann. Wandle den Datentyp vor der Berechnung von Werten, die seinen Bereich überschreiten können, in einen größeren um. - 12HerausforderungEinen fehlenden Messwert erhalten
Du hast
a = np.array([5, 7, 9])und musst den mittleren Messwert als fehlend markieren. Welche Vorbereitung benötigt das Array, bevor du NaN zuweist?---reveal---
Wandle in Gleitkommaspeicherung um:
a = a.astype(float), und setze danna[1] = np.nan. Ganzzahlspeicherung kann NaN nicht darstellen. Das Ergebnis ist[5. nan 9.]; die Ersetzung durch null würde einen Zahlenwert erfassen, statt eine fehlende Messung zu markieren. - 13HerausforderungErstellung und spätere Aktualisierung kombinieren
Du erstellst
template = np.array([1, 2])und benötigst dann ein Array derselben Form, dessen Werte später 1,5 und NaN enthalten können. Welche Wahl bei der Erstellung ermöglicht diese Werte?---reveal---
Verwende einen Gleitkomma-Datentyp, zum Beispiel
np.zeros_like(template, dtype=float). Die like-Funktion würde standardmäßig die Ganzzahlspeicherung übernehmen. Die Form kann(2,)bleiben, während die Wahl eines Gleitkommatyps sowohl den Messwert mit Nachkommastelle als auch das Fehlwertkennzeichen erlaubt. - 14ZusammenfassungDie Struktur vor dem Rechnen prüfen
Prüfe beim nächsten Array, das du erstellst,
shape,sizeunddtype, bevor du arithmetische Operationen anwendest. Prüfe, ob jede Achse die beabsichtigte Wertegruppe darstellt und ob der Speicher die Messwerte aufnehmen kann, die du zuweisen wirst.Wähle beim Erzeugen eines Gitters bewusst eine Punktanzahl oder eine Schrittweite. Wenn Dezimalwerte oder NaN auftreten werden, plane Gleitkommaspeicherung ein, bevor du diese Werte in das Array schreibst.
2Datensätze auswählen und die Auswirkungen von Änderungen steuern
16 Schritte
Speichere diese Einheit, um jede Interaktive Lektion Schritt für Schritt durchzugehen.
- 1EinführungFragen, welche Werte zum Ergebnis gehören
- 2ErklärungStart, Stopp und Schrittweite verfolgen
- 3BeispielZeilen und Spalten in einem Ausdruck auswählen
- 4HerausforderungEine Spaltenachse erhalten
- 5BeispielEinen Schreibvorgang über eine Sicht verfolgen
- 6TippUnabhängigkeit ausdrücklich herstellen
- 7ErklärungKoordinaten paaren oder einen Block auswählen
- 8HerausforderungEine Kopie von einer direkten Zuweisung unterscheiden
- 9ErklärungEine Bedingung in eine Auswahl umwandeln
- 10BeispielIntervallschranken verknüpfen
- 11KernaussageEreignisse zählen oder den Mittelwert ihrer Werte berechnen
- 12BeispielErsetzen oder Filtern wählen
- 13HerausforderungVollständige Zeilen erhalten
- 14TippNaN ohne Gleichheitsvergleich finden
- 15HerausforderungAusgewählte Datensätze unabhängig aktualisieren
- 16ZusammenfassungDas Ziel jeder Bearbeitung prüfen
3Werten die richtige Form und Gruppierung geben
12 Schritte
Speichere diese Einheit, um jede Interaktive Lektion Schritt für Schritt durchzugehen.
- 1EinführungDie Gruppierung in der Form sichtbar machen
- 2BeispielAufeinanderfolgende Werte zu Perioden gruppieren
- 3ErklärungEine fehlende Dimension ermitteln
- 4BeispielDie Bedeutung von Zeilen und Spalten vertauschen
- 5HerausforderungEine Spalte aus einem Vektor erstellen
- 6TippDas Abflachen im Hinblick auf spätere Bearbeitung wählen
- 7ErklärungEine vorhandene Achse erweitern
- 8BeispielStattdessen eine Stapelachse hinzufügen
- 9HerausforderungZwei Messwertspalten erstellen
- 10BeispielAn Grenzen oder nach Anzahl der Teile aufteilen
- 11HerausforderungEine Tabelle aus Zeilenstapeln wiederherstellen
- 12ZusammenfassungFormen als Entscheidungen über Daten verstehen
4Ohne Python-Schleife über Datensätze hinweg rechnen
15 Schritte
Speichere diese Einheit, um jede Interaktive Lektion Schritt für Schritt durchzugehen.
- 1EinführungDen Ausdruck die Berechnung beschreiben lassen
- 2BeispielGepaarte Werte multiplizieren und summieren
- 3ErklärungDen richtigen Produktoperator verwenden
- 4TippZiel und Nenner prüfen
- 5HerausforderungDen Bezugswert für eine prozentuale Änderung wählen
- 6ErklärungMathematische Funktionen auf Arrays anwenden
- 7BeispielAbstände schrittweise berechnen
- 8HerausforderungMaximum mit einer Reduktion vergleichen
- 9TippRundung und ungültige Werte prüfen
- 10ErklärungFormen von ihren rechten Enden ausrichten
- 11BeispielZeilenmittelwerte als Spalte erhalten
- 12KernaussageEin gültiges Broadcasting kann die falsche Frage beantworten
- 13HerausforderungEin Broadcasting-Ergebnis vorhersagen
- 14HerausforderungZentrierte Messwerte gewichten
- 15ZusammenfassungWerte, Paarung und Ausgabeform prüfen
5Die Beobachtungen zusammenfassen, die deine Frage beantworten
15 Schritte
Speichere diese Einheit, um jede Interaktive Lektion Schritt für Schritt durchzugehen.
- 1EinführungDie Frage vor dem Kennwert wählen
- 2BeispielDie Messwertachse reduzieren
- 3KernaussageVerfolgen, was die Reduktion übersteht
- 4BeispielPosition, Wert und kumulative Summe unterscheiden
- 5HerausforderungDen Divisor der Varianz wählen
- 6BeispielMedian und Perzentil bestimmen
- 7TippDatensätze über Positionen sortieren
- 8HerausforderungEine Bezeichnung anhand ihrer Häufigkeit finden
- 9ErklärungFehlende Werte bewusst überspringen
- 10BeispielEinen Fehlwertcode vor der Mittelwertberechnung umwandeln
- 11KernaussageAuffüllen erzeugt Beobachtungen für die Berechnung
- 12BeispielEine Vollständigkeitsentscheidung pro Zeile erstellen
- 13HerausforderungEine leere Teilmenge erkennen
- 14HerausforderungGruppen zusammenfassen und vergleichen
- 15ZusammenfassungBerichten, was zu jeder Zusammenfassung beigetragen hat
6Eine reproduzierbare Simulation von den Ziehungen bis zu den Ergebnissen durchführen
14 Schritte
Speichere diese Einheit, um jede Interaktive Lektion Schritt für Schritt durchzugehen.
- 1EinführungJedem simulierten Versuchsdurchlauf eine klare Form geben
- 2ErklärungDen Generator einmal erstellen
- 3BeispielParameter für Ganzzahl- und Normalverteilungsziehungen festlegen
- 4HerausforderungDen Fehler mit wiederholten Zufallszahlen finden
- 5TippÜber Zurücklegen entscheiden und Datensätze erhalten
- 6BeispielEin Ereignis mit einer Maske schätzen
- 7BeispielInnerhalb jedes Versuchs mit zwei Würfeln reduzieren
- 8HerausforderungDas Ereignis auf mindestens einen Würfel ändern
- 9ErklärungStichprobenschwankungen erwarten
- 10BeispielSchritte zu einem Pfad aufsummieren
- 11TippPrüfen, ob die Grenze erreicht wurde
- 12HerausforderungDatensätze genau einmal aufteilen
- 13HerausforderungEntscheiden, was ein viel größerer Lauf beheben kann
- 14ZusammenfassungZuerst das Modell und dann seine Genauigkeit prüfen
NumPy-Arrays: Übungsaufgaben
Set 1: Arrays lesen und die richtige Operation wählen10 Übungsfragen
Frage 1 von 10
Antwort zeigenAntwort ausblenden
(8, 5). (5, 8) vertauscht die Rollen von Datensätzen und Messwerten. Insgesamt gibt es 40 Elemente, aber diese Elementanzahl ersetzt nicht die Form mit zwei Achsen.Frage 2 von 10
Antwort zeigenAntwort ausblenden
np.linspace(0, 3, 7) einen Abstand von 0,5 m und schließt beide Endpunkte ein. np.arange(0, 3, 0.5) stoppt vor 3 und ergibt nur sechs Punkte. Bei linspace zählt das dritte Argument Punkte, keine Abstände.Frage 3 von 10
np.array([4.9, -4.9]).astype(int)?Antwort zeigenAntwort ausblenden
astype(int) entfernt den Nachkommateil in Richtung null und ergibt 4 und −4. Das Ergebnis [5, -5] würde voraussetzen, dass zuerst zur nächsten Zahl gerundet wird. Die Ganzzahldivision verwendet bei negativen Werten eine andere Richtung und beschreibt diese Umwandlung nicht.Frage 4 von 10
(v >= 8).mean() für v = np.array([2, 8, 11, 5, 14]) zurück?Antwort zeigenAntwort ausblenden
Frage 5 von 10
[batch_id, mass_kg]: d = np.array([[1, 4], [2, 9], [1, 7], [2, 5]]). Wie groß ist die mittlere Masse der Datensätze aus Charge 1, deren Masse größer als 5 kg ist?Antwort zeigenAntwort ausblenden
[1, 7] bleibt übrig, daher beträgt die mittlere Masse 7,0 kg. Ein Mittelwert von 5,5 kg umfasst beide Datensätze aus Charge 1 und berücksichtigt die Massenbedingung nicht; 8,0 kg ignoriert die Chargenbedingung.Frage 6 von 10
np.arange(8).reshape(2, 4).T[1]?Antwort zeigenAntwort ausblenden
[0, 1, 2, 3] und [4, 5, 6, 7]. Das Transponieren macht deren zweite Spalte zur Zeile 1, [1, 5]. Das Ergebnis [2, 3] würde die ursprüngliche Folge in Zeilen der Länge zwei neu gruppieren; das ist ein Umformen und kein Vertauschen der Achsen.Frage 7 von 10
np.array([5., 8.]) und neue Preise sind np.array([6., 6.]). Welche prozentualen Änderungen ergibt (new - old) / old * 100?Antwort zeigenAntwort ausblenden
Frage 8 von 10
Antwort zeigenAntwort ausblenden
cumsum(axis=1) erhält für jeden Tag eine kumulative Summe, statt nur eine Summe pro Maschine zurückzugeben.Frage 9 von 10
d = np.array([[9, 30], [2, 80], [5, 40]]). Wie kannst du die Datensätze nach ihrer ersten Spalte aufsteigend sortieren und dabei jede Zeile zusammenhalten?Antwort zeigenAntwort ausblenden
argsort() ergibt die Zeilenpositionen in der Reihenfolge 1, 2, 0. Werden diese Positionen auf d angewendet, werden vollständige Datensätze verschoben. Das unabhängige Sortieren der Spalten mit np.sort(d, axis=0) würde die Werte der ersten Spalte von den ursprünglich zugehörigen Werten der zweiten Spalte trennen.Frage 10 von 10
Antwort zeigenAntwort ausblenden
Set 2: Auswahlen, Formen und Zusammenfassungen verknüpfen10 Übungsfragen
Speichere diese Einheit, um jede Antwort zu sehen und jedes Set zu üben.
Frage 1 von 10
np.arange(4, 16, 5)?Antwort zeigenAntwort ausblenden
Speichere diese Einheit, um diese Antwort zu sehen.
Frage 2 von 10
np.full_like(template, 1.8) nach template = np.array([2, 4, 6]) mit dem Standarddatentyp?Antwort zeigenAntwort ausblenden
Speichere diese Einheit, um diese Antwort zu sehen.
Frage 3 von 10
a nach a = np.arange(7); b = a[1:5]; c = a[[1, 4]]; b[1] = 90; c[0] = 80?Antwort zeigenAntwort ausblenden
Speichere diese Einheit, um diese Antwort zu sehen.
Frage 4 von 10
a[1:6:2] für a = np.array([3, 6, 9, 12, 15, 18, 21]) aus?Antwort zeigenAntwort ausblenden
Speichere diese Einheit, um diese Antwort zu sehen.
Frage 5 von 10
a und b haben die Formen (3, 2) und (3, 5). Welche Form hat np.concatenate([a, b], axis=1)?Antwort zeigenAntwort ausblenden
Speichere diese Einheit, um diese Antwort zu sehen.
Frage 6 von 10
np.floor(x) - np.trunc(x) für x = np.array([-3.5, 2.5])?Antwort zeigenAntwort ausblenden
Speichere diese Einheit, um diese Antwort zu sehen.
Frage 7 von 10
x = np.array([6., 8.]) und y = np.array([8., 15.]) in Metern sollen nur Punkte höchstens 12 m vom Ursprung entfernt behalten werden. Welche Abstände bleiben übrig?Antwort zeigenAntwort ausblenden
Speichere diese Einheit, um diese Antwort zu sehen.
Frage 8 von 10
x = np.array([10., np.nan, 16., np.nan, 22.]) der Mittelwert, nachdem jedes NaN durch null ersetzt wurde?Antwort zeigenAntwort ausblenden
Speichere diese Einheit, um diese Antwort zu sehen.
Frage 9 von 10
rng.choice(np.arange(5), size=6, replace=False)?Antwort zeigenAntwort ausblenden
Speichere diese Einheit, um diese Antwort zu sehen.
Frage 10 von 10
dice enthält 60.000 Versuchsdurchläufe mit drei fairen Würfeln und hat die Form (60000, 3). Welcher Ausdruck schätzt die Wahrscheinlichkeit, dass ein Versuchsdurchlauf mindestens eine 6 enthält?Antwort zeigenAntwort ausblenden
Speichere diese Einheit, um diese Antwort zu sehen.
Set 3: Daten durch mehrere Array-Operationen verfolgen10 Übungsfragen
Speichere diese Einheit, um jede Antwort zu sehen und jedes Set zu üben.
Frage 1 von 10
a = np.array([8, 12]); a[0] = 3.7; b = a / 2?Antwort zeigenAntwort ausblenden
Speichere diese Einheit, um diese Antwort zu sehen.
Frage 2 von 10
m[1:3, 2:3] für m = np.arange(20).reshape(4, 5)?Antwort zeigenAntwort ausblenden
Speichere diese Einheit, um diese Antwort zu sehen.
Frage 3 von 10
t[1, :, 2:4] für ein Array t der Form (3, 4, 5)?Antwort zeigenAntwort ausblenden
Speichere diese Einheit, um diese Antwort zu sehen.
Frage 4 von 10
v = np.arange(1, 13) werden in vier aufeinanderfolgende Perioden von je drei Stunden gruppiert. Wie lautet die erste Zeile, nachdem die Periodenachse und die Achse der Positionen innerhalb der Perioden vertauscht wurden?Antwort zeigenAntwort ausblenden
Speichere diese Einheit, um diese Antwort zu sehen.
Frage 5 von 10
np.array_split(np.arange(14), 4)?Antwort zeigenAntwort ausblenden
Speichere diese Einheit, um diese Antwort zu sehen.
Frage 6 von 10
A * A für A = np.array([[2, 3], [4, 5]]) zurück?Antwort zeigenAntwort ausblenden
Speichere diese Einheit, um diese Antwort zu sehen.
Frage 7 von 10
X sind [2., 6.] und [8., 12.]. Von jeder Zeile soll ihr eigener Mittelwert subtrahiert werden. Welches Ergebnis liefert der fehlerhafte Ausdruck X - X.mean(axis=1) tatsächlich?Antwort zeigenAntwort ausblenden
Speichere diese Einheit, um diese Antwort zu sehen.
Frage 8 von 10
x.var(ddof=1) für x = np.array([1., 3., 5.])?Antwort zeigenAntwort ausblenden
Speichere diese Einheit, um diese Antwort zu sehen.
Frage 9 von 10
np.percentile([4, 8, 12, 20], 25) bei der standardmäßigen Interpolation von NumPy?Antwort zeigenAntwort ausblenden
Speichere diese Einheit, um diese Antwort zu sehen.
Frage 10 von 10
steps enthält fünf ±1-Schritte für eine Zufallsbewegung. Du benötigst den Anteil der Bewegungen, die bei irgendeinem aufgezeichneten Schritt mindestens 3 Einheiten vom Start entfernt sind. Welcher Ausdruck berechnet diesen Anteil?Antwort zeigenAntwort ausblenden
Speichere diese Einheit, um diese Antwort zu sehen.
Set 4: Plausibel wirkende Ergebnisse untersuchen10 Übungsfragen
Speichere diese Einheit, um jede Antwort zu sehen und jedes Set zu üben.
Frage 1 von 10
a hat die Form (6, 4) und itemsize == 8. Du führst b = a[::2, 1:] und dann c = b[:, ::2].copy() aus. Wie viele Byte Elementspeicher hat c?Antwort zeigenAntwort ausblenden
Speichere diese Einheit, um diese Antwort zu sehen.
Frage 2 von 10
np.array([4, 7]) * 3?Antwort zeigenAntwort ausblenden
Speichere diese Einheit, um diese Antwort zu sehen.
Frage 3 von 10
m[[0, 2], [1, 3]] für m = np.arange(12).reshape(3, 4)?Antwort zeigenAntwort ausblenden
Speichere diese Einheit, um diese Antwort zu sehen.
Frage 4 von 10
[group, reading] in d sind [[1., 6.], [2., np.nan], [1., 10.], [2., 14.], [1., np.nan]]. Wie erhältst du den Mittelwert der vorhandenen Messwerte in Gruppe 1?Antwort zeigenAntwort ausblenden
Speichere diese Einheit, um diese Antwort zu sehen.
Frage 5 von 10
v = np.arange(5) die Formen v.T.shape und v[:, np.newaxis].shape zueinander?Antwort zeigenAntwort ausblenden
Speichere diese Einheit, um diese Antwort zu sehen.
Frage 6 von 10
np.maximum(x, 3) für x = np.array([-4., 2., 7.])?Antwort zeigenAntwort ausblenden
Speichere diese Einheit, um diese Antwort zu sehen.
Frage 7 von 10
(3, 2) enthält gepaarte Werte für drei Datensätze. Ein Vektor offset der Länge drei gibt eine Korrektur pro Datensatz an. Jede Korrektur soll zu beiden Werten ihres eigenen Datensatzes addiert werden. Welcher Ausdruck und welche Ergebnisform passen?Antwort zeigenAntwort ausblenden
Speichere diese Einheit, um diese Antwort zu sehen.
Frage 8 von 10
values, counts = np.unique([4, 9, 4, 2, 9, 9], return_counts=True). Was gibt values[counts.argmax()] zurück?Antwort zeigenAntwort ausblenden
Speichere diese Einheit, um diese Antwort zu sehen.
Frage 9 von 10
np.nanmean(D, axis=0) für D = np.array([[2., 4.], [np.nan, 6.], [8., np.nan]]) zurück?Antwort zeigenAntwort ausblenden
Speichere diese Einheit, um diese Antwort zu sehen.
Frage 10 von 10
ids = np.arange(6) und ein separates Messwert-Array haben dieselbe Datensatzreihenfolge. Du benötigst vier Trainingsdatensätze und zwei Testdatensätze mit passenden Kennungen und Messwerten und ohne Überschneidung. Welches Vorgehen garantiert dies?Antwort zeigenAntwort ausblenden
Speichere diese Einheit, um diese Antwort zu sehen.
Set 5: Array-Werkzeuge in vollständigen Analysen kombinieren10 Übungsfragen
Speichere diese Einheit, um jede Antwort zu sehen und jedes Set zu üben.
Frage 1 von 10
np.array([5, -999, 9]), wobei −999 fehlend bedeutet. Gesucht ist der beobachtete Mittelwert, nachdem zu jedem vorhandenen Messwert eine Korrektur von 0,5 addiert wurde. Was ist das richtige Ergebnis?Antwort zeigenAntwort ausblenden
Speichere diese Einheit, um diese Antwort zu sehen.
Frage 2 von 10
a = np.array([2, 5, 8, 11]); b = a[1:]; c = b[[0, 2]]; b[0] = 20; c[1] = 30; a[[0, 3]] = c. Was ist a anschließend?Antwort zeigenAntwort ausblenden
Speichere diese Einheit, um diese Antwort zu sehen.
Frage 3 von 10
x = np.array([1., np.nan, 4., 7.]) suchst du den Anteil der beobachteten Werte, die größer als 3 sind. Wie groß ist dieser Anteil?Antwort zeigenAntwort ausblenden
Speichere diese Einheit, um diese Antwort zu sehen.
Frage 4 von 10
(2, 3). Welche Form ergibt np.stack([a, b], axis=1)?Antwort zeigenAntwort ausblenden
Speichere diese Einheit, um diese Antwort zu sehen.
Frage 5 von 10
a = np.array([3, 6]) benötigst du die Werte [3.5, 6.5]. Warum funktioniert a = a + 0.5, während a += 0.5 einen Fehler auslöst?Antwort zeigenAntwort ausblenden
Speichere diese Einheit, um diese Antwort zu sehen.
Frage 6 von 10
X = np.array([[2., 6., 10.], [4., 8., 12.]]) wird innerhalb jeder Zeile separat zentriert. Welches Ergebnis sollte der richtige Ausdruck erzeugen?Antwort zeigenAntwort ausblenden
Speichere diese Einheit, um diese Antwort zu sehen.
Frage 7 von 10
X = np.array([[3., 9.], [5., 7.], [8., 4.]]) enthält zwei Messwerte. Zentriere jede Zeile, gewichte dann die erste Spalte mit 0,25 und die zweite mit 0,75 und addiere innerhalb jeder Zeile. Was ergibt sich?Antwort zeigenAntwort ausblenden
Speichere diese Einheit, um diese Antwort zu sehen.
Frage 8 von 10
x.argmax() für x = np.array([7, 12, 12, 4])?Antwort zeigenAntwort ausblenden
Speichere diese Einheit, um diese Antwort zu sehen.
Frage 9 von 10
[group, reading] in D sind [[1., 4.], [1., np.nan], [2., 8.], [2., 10.], [2., np.nan]]. Fülle jeden fehlenden Messwert mit dem beobachteten Mittelwert seiner eigenen Gruppe auf. Wie groß ist der Mittelwert aller fünf aufgefüllten Messwerte?Antwort zeigenAntwort ausblenden
Speichere diese Einheit, um diese Antwort zu sehen.
Frage 10 von 10
Antwort zeigenAntwort ausblenden
Speichere diese Einheit, um diese Antwort zu sehen.
Hängst du bei deiner eigenen Aufgabe fest? Hausaufgabenhilfe
Schlüsselbegriffe
A
Abflachen
flatten kopiert die Daten, während ravel die ursprünglichen Daten gemeinsam nutzen kann.table.flatten() auf, wenn du ein separates 1-dimensionales Ergebnis benötigst, dessen Bearbeitung die Tabelle nicht ändern kann.Abrundungsfunktion
np.floor wendet dieses Abrunden auf jeden Eingabewert an.np.floor den Wert −3,0, weil −2 oberhalb des negativen Ausgangswerts liegen würde.Abschneiden der Nachkommastellen
astype(int) ergibt −7; die Anwendung von floor würde dagegen −8 ergeben.Achse
data[:, 0] alle Positionen auf der Zeilenachse und nimmt die erste Spalte.Achse der Länge eins
[:, None] zu einem Vektor der Länge vier erzeugt die Form (4, 1), geeignet für einen Wert pro Tabellenzeile.Aggregation
table.mean(axis=0) fasst Datensätze zusammen und ergibt einen Mittelwert für jede Messwertspalte.Aggregation unter Ausschluss von NaN
nanmean oder nanmedian.np.nanmean([5., np.nan, 9.]) gibt 7,0 zurück, indem es den Mittelwert der beiden beobachteten Werte berechnet.Aliasing
b = a ist der Ausdruck b is a wahr, und eine Zuweisung über einen der beiden Namen ändert dieses eine Array.Argmax
[3, 8, 8, 2] gibt argmax den Wert 1 zurück, eine Position statt des maximalen Werts 8.Argsort
names[np.argsort(scores)], um Namen nach Ergebnissen geordnet aufzulisten, ohne die Zuordnung zwischen Namen und Ergebnissen zu verlieren.Array-Erzeugungsfunktion
np.full((3, 2), 8) erstellt drei Zeilen mit je zwei Werten, ohne sechs einzeln geschriebene Eingaben zu benötigen.Aufrundungsfunktion
np.ceil wendet dieses Aufrunden auf Array-Werte an.np.ceil den Wert −2,0, für 2,3 dagegen 3,0.Aufteilen
array_split erlaubt Teile unterschiedlicher Länge.np.arange(9) an [2, 6] ergibt Teile der Längen 2, 4 und 3, weil die Zahlen Grenzen sind.Ä
Äquidistante Unterteilung
linspace erstellt dieses Gitter anhand seiner Endpunkte und der Punktanzahl.B
Bedingte Aggregation
mass[batch == 'B'].mean() berechnet nur den Mittelwert der Massen, deren zugehörige Chargenbezeichnung B ist.Bedingte Auswahl
np.where erstellt ein Ergebnis, indem sie an wahren Positionen eine Eingabe und an falschen Positionen eine andere wählt.np.where(x < 0, 0, x) ersetzt negative Werte in einem neuen Ergebnis derselben gesamten Auswahlform durch null.Binäre ufunc
np.maximum(observed, minimum) wählt an jeder Ausgabeposition den größeren von zwei ausgerichteten Werten.Boolesche Indizierung
data[data[:, 0] > 10] behält ganze Zeilen anhand der auf ihre erste Spalte angewendeten Bedingung.Boolesche Maske
t > 25 die Tage, deren erfasste Temperatur 25 °C übersteigt.Broadcasting
(3,) zu einer Tabelle der Form (8, 3) wendet diesen Vektor auf jede der acht Zeilen an.D
Datentyp (dtype)
data.dtype kann zeigen, dass eine verirrte Textbezeichnung dazu geführt hat, dass numerisch aussehende Werte als Zeichenketten gespeichert wurden.Definitionsbereich
np.sqrt(-4.0) gibt normalerweise eine Warnung und NaN zurück.E
Einheitsmatrix
np.eye erzeugt.np.eye(4) erzeugt vier Einsen auf der Diagonalen eines 4 × 4 Arrays und Nullen an den übrigen Positionen.Elementanzahl
(4, 7) hat die Elementanzahl 28, obwohl sein Attribut ndim nur zwei Achsen angibt.Elementweise Arithmetik
(2, 3) mit * ergibt sechs gepaarte Produkte in einem weiteren Array der Form (2, 3).Elementweise logische Operation
&, | oder ~ für UND, ODER beziehungsweise Negation.(x >= 2) & (x <= 8) behält Werte, die beide Schranken erfüllen; jeder Vergleich steht in Klammern.Erste Treffzeit
F
Fancy Indexing
a[[4, 1, 4]] enthält Position 4 zweimal und erhält die angeforderte Ausgabereihenfolge.Fehlwertcode
Form (Shape)
(2, 6) beschreibt zwei Zeilen mit je sechs Werten, während die Form (12,) einen Vektor mit zwölf Werten beschreibt.Freiheitsgradkorrektur
ddof fest, wie viel von der Anzahl der Werte im Divisor einer Varianz oder Standardabweichung abgezogen wird.ddof=1 dividiert NumPy die Summe der quadrierten Abweichungen durch vier.G
Ganzzahlindex
(8, 3) gibt data[:, 1] nach dem Entfernen der Spaltenachse die Form (8,) zurück.Ganzzahlüberlauf
uint8-Arrays mit 250 und 10 ergibt durch Überlauf 4, weil dieser Datentyp 260 nicht speichern kann.Gemeinsame Speichernutzung
np.shares_memory prüft, ob sich zwei bestimmte Arrays überlappen.Generator
default_rng erstellt und über Methoden wiederverwendet, die seinen internen Zustand fortschreiben.rng.integers setzen die Folge fort; das erneute Erstellen von rng mit demselben Startwert startet sie neu.Gewichtete Summe
(scores * weights).sum(axis=1) erzeugt für jede Zeile ein gewichtetes Ergebnis, wenn die Gewichte zu den Spalten passen.Gleitkommazahl
np.allclose, wenn winzige Darstellungsunterschiede toleriert werden sollen.H
Homogene Speicherung
np.array([2, 3.5]) wird die ganzzahlige Eingabe zu einer Gleitkommazahl, sodass beide Elemente Gleitkommaspeicher nutzen.I
In-place-Operation
+= zu einem Ganzzahl-Array schlägt fehl, während eine gewöhnliche Addition Gleitkommaspeicher erstellen kann.Index
Indizierte Zuweisung
data[:2, 0] = 0 ersetzt die Werte der ersten Spalte in den ersten beiden Zeilen der Tabelle.K
Kompatible Dimensionen
(5, 1) und (4,) werden zu (5, 4) kombiniert, weil ihre ausgerichteten Achsen die Kompatibilitätsregel erfüllen.Koordinatenpaare
m[[0, 2], [1, 3]] wählt die Koordinaten (0, 1) und (2, 3) aus, keinen 2 × 2 Block.Kopie
saved = data[:3].copy() bleibt eine unabhängige Teilmenge für spätere Bearbeitungen oder Vergleiche erhalten.Kumulative Summe
np.cumsum([2, 5, 1]) ergibt [2, 7, 8] und ist nützlich, um einen Kontostand beim Aufsummieren von Einträgen zu verfolgen.M
Median
[1, 3, 6, 100] ist 4,5, obwohl der ungewöhnlich große letzte Wert das arithmetische Mittel stark erhöht.Mittelwertimputation
N
NaN
[4.0, np.nan, 8.0] benötigen Gleitkommaspeicher, und np.isnan erkennt die fehlende Position.ndarray
(50, 3) darstellen.Nicht initialisiertes Array
np.empty(100) nur, wenn der nachfolgende Code jeden Eintrag füllt, bevor eine Berechnung ihn verwendet.Normalverteilung
rng.normal beprobt wird.loc=100 und scale=4 verwendet den Verteilungsmittelwert 100 und die Standardabweichung 4, nicht die Varianz 4.P
Permutation
rng.permutation(n) in disjunkte Index-Slices auf, um jeden Datensatz genau einer Teilmenge zuzuweisen.Perzentil
Pseudozufallsfolge
Q
Quantil
np.quantile(x, 0.75) fordert bei übereinstimmenden Optionen dieselbe Position an wie np.percentile(x, 75).R
Reduktionsachse
keepdims erhalten wird.(6, 4) lässt die Form (6,) mit einem Ergebnis pro ursprünglicher Zeile übrig.S
Schrittweite
np.arange angegeben.np.arange(2, 15, 4) verwendet die Schrittweite 4, um die Folge [2 6 10 14] zu erzeugen.Sicht (View)
b = a[1:4] ändert die Zuweisung b[0] = 50 den Wert a[1], weil der einfache Slice Daten gemeinsam nutzt.Simulation
Slice
a[2:7:2] wählt die Positionen 2, 4 und 6 aus und überspringt jeweils eine Position zwischen den ausgewählten Werten.Spaltenweises Stapeln
np.column_stack, um pro Person einen Datensatz mit zwei Messwerten zu erstellen.Standardabweichung
std() zusammengefasst werden, verwenden standardmäßig den Divisor N; ddof=1 wählt die Stichprobenformel.Standardfehler
Standardisierung
(X - X.mean(axis=0)) / X.std(axis=0) standardisiert Spalten, deren Standardabweichungen nicht null sind.Stapeln
(3, 5) mit einem Eingabevektor pro Zeile.Startwert (Seed)
np.random.default_rng(17) zu Beginn liefert einen wiederholbaren Ausgangspunkt für die Analyse.T
Transponieren
(2, 5) ergibt die Form (5, 2), wobei jede frühere Spalte zu einer Zeile wird.Typumwandlung
astype gibt eine umgewandelte Kopie zurück, und manche Umwandlungen verwerfen Informationen.np.array([2.7, 5.1]).astype(int) wandelt die Werte in 2 und 5 um, ohne zur nächsten Zahl zu runden.U
Umformen
(4, 3) umgeformt, wenn jede Zeile die drei Monate eines Quartals enthalten soll.Unäre ufunc
np.abs auf einem Vektor vorzeichenbehafteter Fehler erzeugt einen Vektor mit deren Beträgen.Unendlich
inf oder -inf geschrieben und als nicht endlich erkannt.inf mit einer Warnung.Universelle Funktion
np.sqrt(distances_squared) berechnet an jeder Position eine Quadratwurzel, ohne Pythons math.sqrt für einzelne Zahlen zu verwenden.Unterschiedliche Werte
np.unique gibt sie sortiert zurück und kann zusätzlich ihre zugehörigen Häufigkeiten zurückgeben.V
Vektorisierung
price * quantity berechnet jede Positionssumme ohne separate Python-Schleife über die Artikel.Verkettung
(2, 4) und (5, 4) entlang Achse 0 ergibt eine Tabelle mit sieben Zeilen und vier Spalten.Versuchsdurchlauf
Vollständige Zeile
~np.isnan(data).any(axis=1) erzeugt für jeden vollständigen Datensatz einer numerischen Tabelle einen wahren Eintrag.W
Wertbegrenzung (Clipping)
np.clip(readings, 10, 30) behält Werte innerhalb des Bereichs und ersetzt Messwerte außerhalb durch 10 oder 30.Z
Zeilenweise Speicheranordnung
[0, 1, 2, 3, 4, 5] zu (2, 3) setzt [0, 1, 2] in die erste Zeile.Zentrierung
X - X.mean(axis=0) subtrahiert den Mittelwert jeder Spalte von den Werten derselben Spalte.Ziehen mit Zurücklegen
rng.choice.Zufallsbewegung (Random Walk)
cumsum(axis=1) erzeugen separate Positionen der Zufallsbewegung entlang jeder Versuchszeile.Über diese Einheit
Erstelle deine eigenen Lernmaterialien
Mach aus deinen Notizen, Folien und Dokumenten Lernleitfäden, Übungsfragen, Karteikarten und 6 weitere Tools.