Kapitel 1. Arbeiten mit Vektoren, Matrizenund Arrays in NumPy
Diese Arbeit wurde mithilfe von KI übersetzt. Wir freuen uns über dein Feedback und deine Kommentare: translation-feedback@oreilly.com
1.0 Einleitung
NumPy ist ein grundlegendes Werkzeug des Python-Stacks für maschinelles Lernen. NumPy ermöglicht effiziente Operationen mit den Datenstrukturen, die beim maschinellen Lernen häufig verwendet werden: Vektoren, Matrizen und Tensoren. Obwohl NumPy nicht im Mittelpunkt dieses Buches steht, wird es in den folgenden Kapiteln häufig auftauchen. In diesem Kapitel werden die gängigsten NumPy-Operationen behandelt, mit denen wir bei der Arbeit an Workflows für maschinelles Lernen wahrscheinlich konfrontiert werden.
1.1 Erstellen eines Vektors
Lösung
Verwende NumPy, um ein eindimensionales Array zu erstellen:
# Load library
import
numpy
as
np
# Create a vector as a row
vector_row
=
np
.
array
([
1
,
2
,
3
])
# Create a vector as a column
vector_column
=
np
.
array
([[
1
],
[
2
],
[
3
]])
Diskussion
Die wichtigste Datenstruktur von NumPy ist das mehrdimensionale Array. Ein Vektor ist nur ein Array mit einer einzigen Dimension. Um einen Vektor zu erstellen, legen wir einfach ein eindimensionales Array an. Genau wie Vektoren können diese Arrays horizontal (d. h. in Zeilen) oder vertikal (d. h. in Spalten) dargestellt werden.
1.2 Erstellen einer Matrix
Diskussion
Um eine Matrix zu erstellen, können wir ein zweidimensionales NumPy-Array verwenden. In unserer Lösung enthält die Matrix drei Zeilen und zwei Spalten (eine Spalte mit 1en und eine Spalte mit 2en).
NumPy hat eine eigene Datenstruktur für Matrizen:
matrix_object
=
np
.
mat
([[
1
,
2
],
[
1
,
2
],
[
1
,
2
]])
matrix([[1, 2], [1, 2], [1, 2]])
Die Matrix-Datenstruktur wird jedoch aus zwei Gründen nicht empfohlen. Erstens sind Arrays de facto die Standard-Datenstruktur von NumPy. Zweitens geben die allermeisten NumPy-Operationen Arrays und keine Matrixobjekte zurück.
Siehe auch
1.3 Erstellen einer spärlichen Matrix
Lösung
Erstelle eine spärliche Matrix:
# Load libraries
import
numpy
as
np
from
scipy
import
sparse
# Create a matrix
matrix
=
np
.
array
([[
0
,
0
],
[
0
,
1
],
[
3
,
0
]])
# Create compressed sparse row (CSR) matrix
matrix_sparse
=
sparse
.
csr_matrix
(
matrix
)
Diskussion
Beim maschinellen Lernen kommt es häufig vor, dass eine große Menge an Daten vorliegt, die meisten Elemente in den Daten aber Nullen sind. Stell dir zum Beispiel eine Matrix vor, in der die Spalten alle Filme auf Netflix sind, die Zeilen alle Netflix-Nutzer und die Werte die Anzahl der Filme, die ein Nutzer gesehen hat. Diese Matrix würde Zehntausende von Spalten und Millionen von Zeilen haben! Da die meisten Nutzerinnen und Nutzer jedoch nicht die meisten Filme ansehen, wäre die große Mehrheit der Elemente gleich null.
Eine dünnbesetzte Matrix ist eine Matrix, in der die meisten Elemente 0 sind. Dünnbesetzte Matrizen speichern nur Elemente, die nicht Null sind, und gehen davon aus, dass alle anderen Werte Null sind, was zu einer erheblichen Rechenersparnis führt. In unserer Lösung haben wir ein NumPy-Array mit zwei Nicht-Null-Werten erstellt und es dann in eine Sparse-Matrix umgewandelt. Wenn wir uns die Sparse-Matrix ansehen, können wir sehen, dass nur die Nicht-Null-Werte gespeichert werden:
# View sparse matrix
(
matrix_sparse
)
(1, 1) 1 (2, 0) 3
Es gibt eine Reihe von Arten von Sparse-Matrizen. In komprimierten Sparrow-Matrizen (CSR) stehen (1, 1)
und (2, 0)
für die (mit Null indizierten) Indizes der Nicht-Null-Werte 1
bzw. 3
. Zum Beispiel befindet sich das Element 1
in der zweiten Zeile und der zweiten Spalte. Wir können den Vorteil von dünnbesetzten Matrizen sehen, wenn wir eine viel größere Matrix mit viel mehr Nullelementen erstellen und dann diese größere Matrix mit unserer ursprünglichen dünnbesetzten Matrix vergleichen:
# Create larger matrix
matrix_large
=
np
.
array
([[
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
],
[
0
,
1
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
],
[
3
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
]])
# Create compressed sparse row (CSR) matrix
matrix_large_sparse
=
sparse
.
csr_matrix
(
matrix_large
)
# View original sparse matrix
(
matrix_sparse
)
(1, 1) 1 (2, 0) 3
# View larger sparse matrix
(
matrix_large_sparse
)
(1, 1) 1 (2, 0) 3
Wie wir sehen können, ist die dünnbesetzte Darstellung der größeren Matrix genau dieselbe wie unsere ursprüngliche dünnbesetzte Matrix, obwohl wir viel mehr Nullelemente hinzugefügt haben. Das heißt, das Hinzufügen von Nullelementen hat die Größe der spärlichen Matrix nicht verändert.
Wie bereits erwähnt, gibt es viele verschiedene Arten von Sparse-Matrizen, z. B. komprimierte Sparse-Spalten, Listen von Listen und Wörterbücher von Schlüsseln. Obwohl eine Erläuterung der verschiedenen Arten und ihrer Auswirkungen den Rahmen dieses Buches sprengen würde, sei darauf hingewiesen, dass es zwar keinen "besten" Sparse-Matrixtyp gibt, dass es aber bedeutsame Unterschiede zwischen ihnen gibt und dass wir uns bewusst machen sollten, warum wir eine Art gegenüber einer anderen wählen.
1.4 Vorbelegung von NumPy-Arrays
Lösung
NumPy hat Funktionen zum Erzeugen von Vektoren und Matrizen beliebiger Größe mit 0en, 1en oder Werten deiner Wahl:
# Load library
import
numpy
as
np
# Generate a vector of shape (1,5) containing all zeros
vector
=
np
.
zeros
(
shape
=
5
)
# View the matrix
(
vector
)
array([0., 0., 0., 0., 0.])
# Generate a matrix of shape (3,3) containing all ones
matrix
=
np
.
full
(
shape
=
(
3
,
3
),
fill_value
=
1
)
# View the vector
(
matrix
)
array([[1., 1., 1.], [1., 1., 1.], [1., 1., 1.]])
Diskussion
Das Erzeugen von Arrays, die bereits mit Daten gefüllt sind, ist für eine Reihe von Zwecken nützlich, z. B. um den Code leistungsfähiger zu machen oder synthetische Daten zum Testen von Algorithmen zu verwenden. In vielen Programmiersprachen ist es üblich, ein Array mit Standardwerten (z. B. 0) vorzubelegen.
1.5 Auswählen von Elementen
Lösung
NumPy-Arrays machen es einfach, Elemente in Vektoren oder Matrizen auszuwählen:
# Load library
import
numpy
as
np
# Create row vector
vector
=
np
.
array
([
1
,
2
,
3
,
4
,
5
,
6
])
# Create matrix
matrix
=
np
.
array
([[
1
,
2
,
3
],
[
4
,
5
,
6
],
[
7
,
8
,
9
]])
# Select third element of vector
vector
[
2
]
3
# Select second row, second column
matrix
[
1
,
1
]
5
Diskussion
Wie die meisten Dinge in Python sind auch NumPy-Arrays null-indiziert, was bedeutet, dass der Index des ersten Elements 0 und nicht 1 ist. Unter diesem Vorbehalt bietet NumPy eine Vielzahl von Methoden, um Elemente oder Gruppen von Elementen in Arrays auszuwählen (d.h. zu indizieren und aufzuschlüsseln):
# Select all elements of a vector
vector
[:]
array([1, 2, 3, 4, 5, 6])
# Select everything up to and including the third element
vector
[:
3
]
array([1, 2, 3])
# Select everything after the third element
vector
[
3
:]
array([4, 5, 6])
# Select the last element
vector
[
-
1
]
6
# Reverse the vector
vector
[::
-
1
]
array([6, 5, 4, 3, 2, 1])
# Select the first two rows and all columns of a matrix
matrix
[:
2
,:]
array([[1, 2, 3], [4, 5, 6]])
# Select all rows and the second column
matrix
[:,
1
:
2
]
array([[2], [5], [8]])
1.6 Beschreiben einer Matrix
Lösung
Verwende die Attribute shape
, size
und ndim
eines NumPy-Objekts:
# Load library
import
numpy
as
np
# Create matrix
matrix
=
np
.
array
([[
1
,
2
,
3
,
4
],
[
5
,
6
,
7
,
8
],
[
9
,
10
,
11
,
12
]])
# View number of rows and columns
matrix
.
shape
(3, 4)
# View number of elements (rows * columns)
matrix
.
size
12
# View number of dimensions
matrix
.
ndim
2
Diskussion
Das mag einfach erscheinen (und ist es auch), aber es wird immer wieder nützlich sein, die Form und Größe eines Arrays zu überprüfen, sowohl für weitere Berechnungen als auch einfach als Bauchgefühl nach einer Operation.
1.7 Anwendung von Funktionen auf jedes Element
Lösung
Verwende die NumPy vectorize
Methode:
# Load library
import
numpy
as
np
# Create matrix
matrix
=
np
.
array
([[
1
,
2
,
3
],
[
4
,
5
,
6
],
[
7
,
8
,
9
]])
# Create function that adds 100 to something
add_100
=
lambda
i
:
i
+
100
# Create vectorized function
vectorized_add_100
=
np
.
vectorize
(
add_100
)
# Apply function to all elements in matrix
vectorized_add_100
(
matrix
)
array([[101, 102, 103], [104, 105, 106], [107, 108, 109]])
Diskussion
Die NumPy-Methode vectorize
wandelt eine Funktion in eine Funktion um, die auf alle Elemente in einem Array oder einem Teil eines Arrays angewendet werden kann. Es sei darauf hingewiesen, dass vectorize
im Wesentlichen eine for
Schleife über die Elemente ist und die Leistung nicht erhöht. Außerdem können wir mit NumPy-Arrays Operationen zwischen Arrays durchführen, auch wenn ihre Dimensionen nicht identisch sind (ein Prozess, der Broadcasting genannt wird). Wir können zum Beispiel eine viel einfachere Version unserer Lösung mit Broadcasting erstellen:
# Add 100 to all elements
matrix
+
100
array([[101, 102, 103], [104, 105, 106], [107, 108, 109]])
Broadcasting funktioniert nicht für alle Formen und Situationen, aber es ist eine gängige Methode, um einfache Operationen auf alle Elemente eines NumPy-Arrays anzuwenden.
1.8 Ermittlung der Höchst- und Mindestwerte
Lösung
Verwende die Methoden max
und min
von NumPy:
# Load library
import
numpy
as
np
# Create matrix
matrix
=
np
.
array
([[
1
,
2
,
3
],
[
4
,
5
,
6
],
[
7
,
8
,
9
]])
# Return maximum element
np
.
max
(
matrix
)
9
# Return minimum element
np
.
min
(
matrix
)
1
Diskussion
Oft wollen wir den maximalen und minimalen Wert in einem Array oder einer Teilmenge eines Arrays wissen. Dies kann mit den Methoden max
und min
erreicht werden. Mit dem Parameter axis
können wir die Operation auch entlang einer bestimmten Achse durchführen:
# Find maximum element in each column
np
.
max
(
matrix
,
axis
=
0
)
array([7, 8, 9])
# Find maximum element in each row
np
.
max
(
matrix
,
axis
=
1
)
array([3, 6, 9])
1.9 Berechnung von Durchschnitt, Varianz und Standardabweichung
Diskussion
Genau wie bei max
und min
können wir ganz einfach deskriptive Statistiken über die gesamte Matrix erhalten oder Berechnungen entlang einer einzelnen Achse durchführen:
# Find the mean value in each column
np
.
mean
(
matrix
,
axis
=
0
)
array([ 4., 5., 6.])
1.10 Arrays umgestalten
Lösung
Verwende NumPy's reshape
:
# Load library
import
numpy
as
np
# Create 4x3 matrix
matrix
=
np
.
array
([[
1
,
2
,
3
],
[
4
,
5
,
6
],
[
7
,
8
,
9
],
[
10
,
11
,
12
]])
# Reshape matrix into 2x6 matrix
matrix
.
reshape
(
2
,
6
)
array([[ 1, 2, 3, 4, 5, 6], [ 7, 8, 9, 10, 11, 12]])
Diskussion
reshape
ermöglicht es uns, eine Matrix so umzustrukturieren, dass wir dieselben Daten beibehalten, sie aber in einer anderen Anzahl von Zeilen und Spalten organisieren. Die einzige Voraussetzung ist, dass die ursprüngliche und die neue Matrix die gleiche Anzahl von Elementen enthalten (d.h. die gleiche Größe haben). Wir können die Größe einer Matrix mit size
sehen:
matrix
.
size
12
Ein nützliches Argument in reshape
ist -1
, was so viel bedeutet wie "so viele wie nötig", also bedeutet reshape(1, -1)
eine Zeile und so viele Spalten wie nötig:
matrix
.
reshape
(
1
,
-
1
)
array([[ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]])
Wenn wir eine ganze Zahl angeben, gibt reshape
ein eindimensionales Array mit dieser Länge zurück:
matrix
.
reshape
(
12
)
array([ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12])
1.11 Transponieren eines Vektors oder einer Matrix
Diskussion
Transponieren ist eine gängige Operation in der linearen Algebra, bei der die Spalten- und Zeilenindizes der einzelnen Elemente vertauscht werden. Ein wichtiger Punkt, der in der Regel außerhalb des Linearen Algebra-Unterrichts übersehen wird, ist, dass ein Vektor technisch gesehen nicht transponiert werden kann, weil er nur eine Sammlung von Werten ist:
# Transpose vector
np
.
array
([
1
,
2
,
3
,
4
,
5
,
6
])
.
T
array([1, 2, 3, 4, 5, 6])
Es ist jedoch üblich, das Transponieren eines Vektors als Umwandlung eines Zeilenvektors in einen Spaltenvektor zu bezeichnen (beachte das zweite Klammerpaar) oder umgekehrt:
# Transpose row vector
np
.
array
([[
1
,
2
,
3
,
4
,
5
,
6
]])
.
T
array([[1], [2], [3], [4], [5], [6]])
1.12 Eine Matrix abflachen
Diskussion
flatten
ist eine einfache Methode, um eine Matrix in ein eindimensionales Array umzuwandeln. reshape
Alternativ können wir verwenden, um einen Zeilenvektor zu erstellen:
matrix
.
reshape
(
1
,
-
1
)
array([[1, 2, 3, 4, 5, 6, 7, 8, 9]])
Eine weitere gängige Methode zum Verflachen von Arrays ist die ravel
Methode. Im Gegensatz zu flatten
, die eine Kopie des ursprünglichen Arrays zurückgibt, arbeitet ravel
mit dem ursprünglichen Objekt selbst und ist daher etwas schneller. Außerdem können wir damit Listen von Arrays reduzieren, was mit der Methode flatten
nicht möglich ist. Diese Operation ist nützlich, um sehr große Arrays zu verflachen und den Code zu beschleunigen:
# Create one matrix
matrix_a
=
np
.
array
([[
1
,
2
],
[
3
,
4
]])
# Create a second matrix
matrix_b
=
np
.
array
([[
5
,
6
],
[
7
,
8
]])
# Create a list of matrices
matrix_list
=
[
matrix_a
,
matrix_b
]
# Flatten the entire list of matrices
np
.
ravel
(
matrix_list
)
array([1, 2, 3, 4, 5, 6, 7, 8])
1.13 Den Rang einer Matrix bestimmen
Diskussion
Der Rang einer Matrix ist die Dimension des Vektorraums, der von ihren Spalten oder Zeilen aufgespannt wird. Dank matrix_rank
ist es in NumPy einfach, den Rang einer Matrix zu bestimmen.
Siehe auch
1.14 Ermittlung der Diagonale einer Matrix
Lösung
Verwende NumPy's diagonal
:
# Load library
import
numpy
as
np
# Create matrix
matrix
=
np
.
array
([[
1
,
2
,
3
],
[
2
,
4
,
6
],
[
3
,
8
,
9
]])
# Return diagonal elements
matrix
.
diagonal
()
array([1, 4, 9])
Diskussion
NumPy macht es einfach, die Diagonalelemente einer Matrix mitdiagonal
zu erhalten. Es ist auch möglich, eine Diagonale abseits der Hauptdiagonale zu erhalten, indem du den Parameter offset
verwendest:
# Return diagonal one above the main diagonal
matrix
.
diagonal
(
offset
=
1
)
array([2, 6])
# Return diagonal one below the main diagonal
matrix
.
diagonal
(
offset
=-
1
)
array([2, 8])
1.15 Berechnen der Spur einer Matrix
Lösung
Verwende trace
:
# Load library
import
numpy
as
np
# Create matrix
matrix
=
np
.
array
([[
1
,
2
,
3
],
[
2
,
4
,
6
],
[
3
,
8
,
9
]])
# Return trace
matrix
.
trace
()
14
Diskussion
Die Spur einer Matrix ist die Summe der Diagonalelemente und wird oft in Methoden des maschinellen Lernens verwendet. Mit einem mehrdimensionalen NumPy-Array können wir die -Spur mit trace
berechnen. Alternativ können wir auch die Diagonale einer Matrix zurückgeben und ihre Summe berechnen:
# Return diagonal and sum elements
sum
(
matrix
.
diagonal
())
14
Siehe auch
1.16 Berechnung von Punktprodukten
Diskussion
Das Punktprodukt von zwei Vektoren, und ist definiert als:
wobei ist die Element des Vektors, und ist das Element des Vektors. Wir können die Funktion dot
von NumPy verwenden, um das Punktprodukt zu berechnen. Alternativ können wir in Python 3.5+ auch den neuen @
Operator verwenden:
# Calculate dot product
vector_a
@
vector_b
32
1.17 Addieren und Subtrahieren von Matrizen
Lösung
Verwende NumPy's add
und subtract
:
# Load library
import
numpy
as
np
# Create matrix
matrix_a
=
np
.
array
([[
1
,
1
,
1
],
[
1
,
1
,
1
],
[
1
,
1
,
2
]])
# Create matrix
matrix_b
=
np
.
array
([[
1
,
3
,
1
],
[
1
,
3
,
1
],
[
1
,
3
,
8
]])
# Add two matrices
np
.
add
(
matrix_a
,
matrix_b
)
array([[ 2, 4, 2], [ 2, 4, 2], [ 2, 4, 10]])
# Subtract two matrices
np
.
subtract
(
matrix_a
,
matrix_b
)
array([[ 0, -2, 0], [ 0, -2, 0], [ 0, -2, -6]])
1.18 Matrizen multiplizieren
Lösung
Verwende NumPy's dot
:
# Load library
import
numpy
as
np
# Create matrix
matrix_a
=
np
.
array
([[
1
,
1
],
[
1
,
2
]])
# Create matrix
matrix_b
=
np
.
array
([[
1
,
3
],
[
1
,
2
]])
# Multiply two matrices
np
.
dot
(
matrix_a
,
matrix_b
)
array([[2, 5], [3, 7]])
Diskussion
Alternativ dazu können wir in Python 3.5+ den @
Operator verwenden:
# Multiply two matrices
matrix_a
@
matrix_b
array([[2, 5], [3, 7]])
Wenn wir eine elementweise Multiplikation durchführen wollen, können wir den *
Operator verwenden:
# Multiply two matrices element-wise
matrix_a
*
matrix_b
array([[1, 3], [1, 4]])
Siehe auch
1.19 Eine Matrix invertieren
Lösung
Verwende die Methode der linearen Algebra von NumPy inv
:
# Load library
import
numpy
as
np
# Create matrix
matrix
=
np
.
array
([[
1
,
4
],
[
2
,
5
]])
# Calculate inverse of matrix
np
.
linalg
.
inv
(
matrix
)
array([[-1.66666667, 1.33333333], [ 0.66666667, -0.33333333]])
Diskussion
Die Inverse einer quadratischen Matrix, A, ist eine zweite Matrix, A-1, so dass:
wobei I die Identitätsmatrix ist. In NumPy können wir linalg.inv
verwenden, um A-1 zu berechnen, falls sie existiert. Um dies in Aktion zu sehen, können wir eine Matrix mit ihrem Kehrwert multiplizieren, und das Ergebnis ist die Identitätsmatrix:
# Multiply matrix and its inverse
matrix
@
np
.
linalg
.
inv
(
matrix
)
array([[ 1., 0.], [ 0., 1.]])
Siehe auch
1.20 Zufallswerte generieren
Diskussion
NumPy bietet eine Vielzahl von Möglichkeiten, um Zufallszahlen zu erzeugen - viel mehr, als hier behandelt werden können. In unserer Lösung haben wir Floats generiert, aber es ist auch üblich, ganze Zahlen zu erzeugen:
# Generate three random integers between 0 and 10
np
.
random
.
randint
(
0
,
11
,
3
)
array([3, 7, 9])
Alternativ können wir Zahlen generieren, indem wir sie aus einer Verteilung ziehen (beachte, dass dies technisch gesehen nicht zufällig ist):
# Draw three numbers from a normal distribution with mean 0.0
# and standard deviation of 1.0
np
.
random
.
normal
(
0.0
,
1.0
,
3
)
array([-1.42232584, 1.52006949, -0.29139398])
# Draw three numbers from a logistic distribution with mean 0.0 and scale of 1.0
np
.
random
.
logistic
(
0.0
,
1.0
,
3
)
array([-0.98118713, -0.08939902, 1.46416405])
# Draw three numbers greater than or equal to 1.0 and less than 2.0
np
.
random
.
uniform
(
1.0
,
2.0
,
3
)
array([ 1.47997717, 1.3927848 , 1.83607876])
Schließlich kann es manchmal nützlich sein, dieselben Zufallszahlen mehrmals zu liefern, um vorhersehbare, wiederholbare Ergebnisse zu erhalten. Das können wir erreichen, indem wir den "Seed" (eine ganze Zahl) des Pseudozufallsgenerators festlegen. Zufallsprozesse mit demselben Seed erzeugen immer die gleiche Ausgabe. Wir werden in diesem Buch durchgehend Seeds verwenden, damit der Code, den du in diesem Buch siehst, und der Code, den du auf deinem Computer ausführst, die gleichen Ergebnisse liefert.
Get Maschinelles Lernen mit Python Kochbuch, 2. now with the O’Reilly learning platform.
O’Reilly members experience books, live events, courses curated by job role, and more from O’Reilly and nearly 200 top publishers.