Uke 13 — numpy

Numpy er en av de mestbrukte eksterne biblioteker for Python. Ved bruk av den nye datatypen numpy.array kan vi lagre store mengder numerisk data på en effektiv måte.

For mer detalj, se på https://numpy.org/doc/stable/user/absolute_beginners.html

Eksempler

Her viser vi ting i en REPL - python’s interaktiv modus. Du kan gjøre det samme ved VSCode -> View -> Command Palette -> Python: Start REPL (eller skriv python i terminalen på Mac/Linux). Bruk exit() for å avslutte REPL.

Vi kan lage et array direkte fra en liste og vi kan bruke den samme indeks-notasjonen:

>>> import numpy as np
>>> a = np.array([1., 4., 5., 8.])
>>> a
array([1., 4., 5., 8.])
>>> type(a)
<type 'numpy.ndarray’>
>>> a[:2]
array([1., 4.])
>>> a[3]
8.0
>>> a[1:3] = 99
>>> a
array([1., 99., 99., 8.])
>>> a[:] = 11
>>> a
array([11., 11., 11., 11.])

For flerdimensionale (nøstete) arrays har vi en enklere indeks-notasjon:

>>> a = np.array( [ [1., 2., 3.], [4., 5., 6.] ] )
>>> a[0,0]    # a[0][0]
1.0
>>> a[1,2]    # a[1][2]
6.0
>>> a.shape
(2,3)

Vi kan ha (nesten) så mange dimensjoner vi vil. Her er et 3D array:

>>> b = np.array([[[111., 112.], [121., 122.]], [[211., 212.], [221., 222.]]])
>>> b
array([[[111., 112.],
        [121., 122.]],

       [[211., 212.],
        [221., 222.]]])
>>> b.shape
(2, 2, 2)
>>> b[1,1,1]
222.0
>>> b[0,0,0]
111.0

Oppgave 1

I filen uke_13_oppg_1.py gjør de følgende:

(a) Lag et numpy-array av den følgende lista og bruk nøstet index-notasjon (f.eks a[1, 0]) til å skrive ut verdien 42:

xs = [[83, 1, 22], [117, 52, 3], [14, 42, 784]]

(b) Ta det numpy-arrayet du lagde i (a) og bruk slice notasjon til å skrive ut den andre kolonnen.

(c) Ta igjen numpy-arrayet du lagde i (a) og bruk slice notasjon til å skrive ut verdiene til de to første radene i de to siste kolonnene.

Eksempel - fortsetting

Det finnes flere hjelpefunksjoner for å lage nye arrays. For hver metode nedenfor, kan du fortelle hva skjer?:

>>> np.arange(1., 2., 0.1)   # fast skrittstørrelse
array([1. , 1.1, 1.2, 1.3, 1.4, 1.5, 1.6, 1.7, 1.8, 1.9])

>>> np.linspace(30,40,5)     # fast start/end, fast antall verdier
array([ 30. , 32.5, 35. , 37.5, 40. ])

>>> np.ones((2,3))
array([[ 1., 1., 1.],
       [ 1., 1., 1.]])

>>> np.zeros(7)
array([0., 0., 0., 0., 0., 0., 0.])

>>> np.full((2,2), 7.)
array([[7., 7.], [7., 7.]])

>>> np.random.random_sample((2,2))
array([[0.33896244, 0.75553158],
       [0.42116679, 0.32801477]])

Alle matematiske operasjonene skjer samtidig for alle elementer, vi bør ikke skrive en løkke:

import numpy as np
a = np.arange(10.)
print(a)
# [[ 0.  1.  2.  3.  4.  5.  6.  7.  8.  9.]]
b = a + 7
print(b)
# [[ 7.   8.   9.  10.  11.  12.  13.  14.  15.  16. ]]
c = b ** 2
print(c)
# [[ 49.   64.   81.  100.  121.  144.  169.  196.  225.  256. ]]
print(c - b)
print(a + b)
print(b * a)
print(np.sin(a))

Oppgave 2

I filen uke_13_oppg_2.py, bruk numpy.arange til å lage et numpy-array med alle oddetallene fra 99 (inkludert 99) til 152. Skriv ut resultatet.

Oppgave 3

I filen uke_13_oppg_3.py, bruk numpy.linspace til å lage en numpy-array med 11 elementer som er likt fordelt mellom 2 og 5 (lik forskjell mellom alle elementene). Skriv ut resultatet.

Oppgave 4

I filen uke_13_oppg_4.py, bruk numpy.reshape til å konvertere numpy-arrayet arr til et array med 4 rader og 3 kollonner:

import numpy as np
arr = np.arange(1,13)

Skriv ut resultatet.

Eksempel - fortsetting

Numpy kan også brukes til matriseregning:

>>> a = np.array( [ [1., 2.], [3., 4.] ] )
>>> b = np.array( [ [4., 3.], [2., 1.] ] )
>>> np.dot(a, b)                           # matrise-multiplikasjon ("matrix dot product")
array([[ 8.,  5.],
       [20., 13.]])
>>> a @ b                                  # lettere måte å skrive det samme ("a ganger b")
array([[ 8.,  5.],
       [20., 13.]])
>>> a * b                                  # OBS: ikke matrise-multiplikasjon
array([[4., 6.],
       [6., 4.]])
>>> np.linalg.det(b)                       # determinanten til en matrise
-2.0
>>> np.linalg.inv(b)                       # inversen til en matrise
array([[-0.5,  1.5],
       [ 1. , -2. ]])
>>> b @ np.linalg.inv(b)                   # b ganger sin egen invers er identiteten (hurra)
array([[1., 0.],
       [0., 1.]])

Numpy kan stort sett gjøre alt du trenger med matriser. Alle funksjonene finnes her: https://numpy.org/doc/stable/reference/routines.linalg.html

numpy og matplotlib er enkelt å bruke sammen:

import numpy as np
import matplotlib.pyplot as plt

xs = np.linspace(0, 5, 100) # 100 x-verdier mellom 0 og 5
ys = np.sin(xs) + 1/3 * np.sin(3 * xs) # alle ys med en gang uten løkke!

plt.plot(xs, ys)
plt.show()

Oppgave 5

En polynomisk funksjon av grad tre er gitt av følgende formel:

\[y = ax^3 + bx^2 + cx + d.\]

Last ned uke_13_oppg_5.py og fyll inn funksjonen polynomial slik at den returnerer et numpy-array og programmet tegner en polynomisk funksjon av grad tre. Bruk numpy-funksjonalitet, ikke en løkke.

Eksempel - fortsetting

Vi kan også sammenligne arrays, resultatet blir et array av bool:

>>> a = np.array([[6, 4], [5, 9]])
>>> a >= 6
array([[ True, False],
       [False, True]], dtype=bool)

Slike boolean-arrays kan brukes som index:

>>> a = np.arange(10.)
>>> filt = a ** 2 > 25   # kvadrat større enn 25
>>> a[filt]
array([6., 7., 8., 9.])

Og i vår plot-eksempel:

import numpy as np
import matplotlib.pyplot as plt

xs = np.linspace(0, 5, 100)
ys = np.sin(xs)

ys[ys > 0.5] = 0.5    # Hva skjer her? Hvilke verdier endres?
ys[ys < -0.5] = -0.5  # Hva skjer her? Hvilke verdier endres?

plt.plot(xs, ys)
plt.show()

Oppgave 6

I filen uke_13_oppg_6.py, bruk numpy til å skrive ut alle oddetallene fra numpy-arrayet arr:

import numpy as np
arr = np.arange(42,59)

Bruk bare numpy-funksjonalitet, ikke en løkke. Skriv ut resultatet.

Oppgave 7

I filen uke_13_oppg_7.py, bruk numpy til å bytte ut alle oddetallene fra numpy-arrayet arr med verdien 1:

import numpy as np
arr = np.arange(42,59)

Bruk bare numpy-funksjonalitet, ikke en løkke. Skriv ut resultatet.

Større numpy/matplotlib eksempler (animation er ikke pensum)

Oppgaver

Oppgave 1

Her finner du Oppgave 1.

Oppgave 2

Her finner du Oppgave 2.

Oppgave 3

Her finner du Oppgave 3.

Oppgave 4

Her finner du Oppgave 4.

Oppgave 5

Her finner du Oppgave 5.

Oppgave 6

Her finner du Oppgave 6.

Oppgave 7

Her finner du Oppgave 7.

Oppgave 8