Matrizenrechnung#

Um mit Vektoren und Matrizen nach den Regeln der Mathemaik zu arbeiten, gibt es das Paket NumPy. das den Datentyp numpy.ndarray, kurz array, bereitstellt:

  • Die Indizierung erfolgt analog zu Sequences

  • Import: Wir imporieren die NumPy-Funktionen als Namespace np durch import numpy as np importiert, um den Haupt-Namespace nicht zu überladen.

import numpy as np
import seaborn as sns  # some graphics

Vektoralgebra: 1-dimensionale arrays#

  • nur eine Klammerung, z. B. beim Inputs der array-Funktion und bei der Indizierung

  • Achtung: keine Unterscheidung in Spalten- oder Zeilenvektoren!

v = np.array([3, 2.1, -5])
v
array([ 3. ,  2.1, -5. ])
type(v)
numpy.ndarray
# Vektoren sind 1-dimensional
np.ndim(v) 
1

Die Anzahl der Elemente wird als Länge (engl. length) bezeichnet. Achtung, das ist nicht die geometrische Länge des Vektors!

len(v) 
3

Viele Funktionen lassen sich alternativ als Methoden der Objekte mit Punkt-Notation aufrufen:

print(v.dtype) # data type: Type der Einträge
print(v.ndim)
print(v.mean())
float64
1
0.033333333333333215

Rechnoperationen: Achtung! +, -, *, ** und / sind nun elementweise Operationen.

3*v # Skalarmultiplikation
array([  9. ,   6.3, -15. ])
v + v # Vektoraddition
array([  6. ,   4.2, -10. ])

Das innere Produkt wird im Englischen oft “dot product” genannt.

np.dot(v, v) 
38.41
# alternativ mit dem @ Operator:
v@v
38.41
np.cross(v, v) # Kreuzprodukt
array([0., 0., 0.])
v*v # Achtung elementweise!
array([ 9.  ,  4.41, 25.  ])
v/v # elementweise!
array([1., 1., 1.])
v**3 # elementweise!
array([  27.   ,    9.261, -125.   ])

Matrixalgebra: 2-dimensionale arrays#

Zwei Dimensionen und daher auch zwei Klammeren:

  • erste Dimension: wievielte Zeile = Zeilenindex

  • zweite Dimension: wievielte Spalte = Spaltenindex

A = np.array([[1,  2, np.sqrt(4)],
              [4, -3,      np.pi]])
A
array([[ 1.        ,  2.        ,  2.        ],
       [ 4.        , -3.        ,  3.14159265]])
A.shape # 2x3 Matrix
(2, 3)
np.dot(A, v) # Matrix-Vektor-Produkt
array([ -2.8       , -10.00796327])
# alternativ mit dem @ Operator:
A@v
array([ -2.8       , -10.00796327])
np.dot(v[:2], A) # Vektor-Matrix-Produkt
array([11.4       , -0.3       , 12.59734457])
# alternativ mit dem @ Operator:
v[:2]@A
array([11.4       , -0.3       , 12.59734457])
w = np.array([[1, 2, 3]])
w.shape
(1, 3)
# dot(A, w) gibt einen Fehler. Warum?
w.T # Transponieren
array([[1],
       [2],
       [3]])
w.T.shape
(3, 1)
np.dot(A, w.T) # oder A@w.T
array([[11.        ],
       [ 7.42477796]])

Slicing:

A[:,0] # Ergebnis: 1-dim array
array([1., 4.])
A[:,[0]] # Ergebnis: 2-dim array
array([[1.],
       [4.]])
A = np.array([[3, -2], 
              [0, 12]])
b = np.array([1, 2])

# Lösen des quadratischen Gleichungssystems Ax=b
x = np.linalg.solve(A, b)
x # Ergebnis: 1-dim array, wie b
array([0.44444444, 0.16666667])
c = b.reshape(2,1)
c # 2-dim array
array([[1],
       [2]])

Lösen eines Gleichungssystems:

x = np.linalg.solve(A, c)
x # Ergebnis: 2-dim array, wie c
array([[0.44444444],
       [0.16666667]])

flattening of a 2-dim array into a 1-dim array:

A.ravel()
array([ 3, -2,  0, 12])
# vergleiche:
A
array([[ 3, -2],
       [ 0, 12]])

Aufgabe:

Welche Funktionalitäten bieten folgende Befehle?

  • linspace

  • arange

  • eye

  • ones

  • zeros

  • diag

  • vstack

  • hstack

  • column_stack

  • row_stack

  • reshape

Experimentieren Sie mit den Befehlen!