NumPy
Contents
1.2. NumPy#
NumPy is een python module die gemaakt is voor numerieke berekeningen. Hiermee kan je snel functies uitvoeren op grote lijsten met getallen, waaronder dus ook de lijsten uit het voorgaande voorbeeld.
1.2.1. Importeren#
Je kan NumPy importeren met de volgende regel (op dezelfde manier als dat we import math eerder hebben gebruikt):
import numpy as np
De toevoeging as np hier zorgt ervoor dat we niet telkens numpy. helemaal uit hoeven schrijven. We maken dus eigenlijk een nieuwe, kortere naam aan voor de module, namelijk np. Dat scheelt uiteindelijk een hoop typewerk aangezien we NumPy vaak aan zullen roepen.
1.2.2. Voorbeeld gebruik Numpy functies#
Laten we eens kijken hoe het stukje code wat we eerder geschreven hebben eruit ziet wanneer we deze module gebruiken:
tijd = [0, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1.0]
snelheid = [0.155, 0.164, 0.262, 0.083, 0.285, 0.137, 0.234, 0.139, 0.063, 0.235]
dt = np.diff(tijd)
dx = snelheid * dt
afstand = np.cumsum(dx)
print('dt: ', dt)
print('dx: ', dx)
print('afstand: ', afstand)
dt: [0.1 0.1 0.1 0.1 0.1 0.1 0.1 0.1 0.1 0.1]
dx: [0.0155 0.0164 0.0262 0.0083 0.0285 0.0137 0.0234 0.0139 0.0063 0.0235]
afstand: [0.0155 0.0319 0.0581 0.0664 0.0949 0.1086 0.132 0.1459 0.1522 0.1757]
Zoals je ziet krijgen we exact dezelfde uitkomst, maar dan met een stuk kortere code. Ook komt de code een stuk beter overeen met de formules die je zou verwachten, wat de code beter leesbaar maakt.
Om dit te bereiken maken we gebruik van twee nieuwe functies uit NumPy:
np.diffneemt het verschil tussen elke set opvolgende stappen uit een lijstnp.cumsumbepaalt de cumulatieve som van een lijst
De precieze werking van deze functies staat natuurlijk beschreven in de documentatie van NumPy en kan ook met de help() functie opgezocht worden.
NumPy is ook veel sneller dan de for-loops die we zelf schrijven. Voor de kleine scriptjes waar we hier mee oefenen is dat nog niet zo belangrijk, maar wanneer de berekeningen complexer worden kan dit veel tijd schelen!
1.2.3. Nieuw datatype: Numpy arrays#
Lijsten met getallen in combinatie met Numpy leveren ons een nieuw datatype op. Zie bijvoorbeeld het volgende voorbeeld.
dt = np.diff(tijd)
print(dt)
print(type(dt))
[0.1 0.1 0.1 0.1 0.1 0.1 0.1 0.1 0.1 0.1]
<class 'numpy.ndarray'>
De variabele dt is van het type numpy.ndarray, een n-dimensionale array. Zulke arrays verschillen van lijsten op een paar manieren. Het belangrijkste verschil is dat alle elementen binnen een lijst van een verschillend type kunnen zijn, terwijl alle elementen in een array hetzelfde type zijn (bijvoorbeeld allemaal getallen, of allemaal strings). Om een lijst te converteren naar een Numpy array kunnen we de functie np.array() gebruiken zoals in het voorbeeld hieronder.
lijst_1 = [1, 2, 3, 4]
lijst_2 = [1, 2, 3, '4']
array_1 = np.array(lijst_1)
array_2 = np.array(lijst_2)
print(array_1)
print(array_2)
[1 2 3 4]
['1' '2' '3' '4']
We zien hier ook dat lijst_2 zowel integers als strings bevat, maar dat deze allemaal omgezet worden naar strings zodra we dit naar een array omzetten.
1.2.4. Aanmaken ‘standaard’ arrays#
Er zijn een paar functies geschreven waarmee we in Numpy eenvoudig arrays van een bepaald formaat, met een standaard-opvulling kunnen maken. Bijvoorbeeld voor automatisch oplopende getallen kunnen we de volgende functies gebruiken.
# van 0 t/m 1 in 10 stappen
tijd_1 = np.linspace(0, 1, 10)
# van 0 t/m 1 in 11 stappen is logischer dan in 10 stappen!
tijd_2 = np.linspace(0, 1, 11)
# van 0 tót 1, met tussenstappen van 0.1
tijd_3 = np.arange(0, 1, 0.1)
print(tijd_1)
print(tijd_2)
print(tijd_3)
[0. 0.11111111 0.22222222 0.33333333 0.44444444 0.55555556
0.66666667 0.77777778 0.88888889 1. ]
[0. 0.1 0.2 0.3 0.4 0.5 0.6 0.7 0.8 0.9 1. ]
[0. 0.1 0.2 0.3 0.4 0.5 0.6 0.7 0.8 0.9]
1.2.5. Wiskundige operaties op lijsten / arrays#
Hiervoor zagen we al dat het met numpy mogelijk is om lijsten met elkaar te vermenigvuldigen. Dit deden we in het tweede scriptje met dx = snelheid * dt. Wat er vervolgens gebeurde is dat de getallen in de lijst één voor één met elkaar vermenigvuldigd werden: het 0e element van de ene lijst met het 0de element van de andere, het 1ste element van de ene met het 1e element van de andere, enzovoorts. Het resultaat van al deze berekeningen wordt opgeslagen in het array dx.
Wat NumPy ons ook laat doen is wiskundige operaties in één keer op hele lijsten toepassen. Hiervoor heeft NumPy een grote verzameling aan wiskundige functies. Deze verschillen van die uit math doordat ze geoptimaliseerd zijn voor het gebruik op lijsten.
Zoals ook eerder kan je precies zien welke functies beschikbaar zijn door dir(np) te typen in je console. Hier zullen we dat niet doen omdat deze lijst met functies erg lang is.
Bij het grafisch weergeven van functies, wat we hierna zullen doen, is het vaak nuttig om een lijst met input waarden te genereren. Dit kunnen we doen, zoals we al eerder deden, met de ingebouwde functie range(), maar NumPy heeft hier een slimmere en snellere functie voor: np.linspace(). Hiermee kan je snel een lijst met lineair oplopende getallen genereren:
getallen = np.linspace(-5, 15, 21)
print(getallen)
[-5. -4. -3. -2. -1. 0. 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12.
13. 14. 15.]
def f(x):
return np.arccos(x)
x = np.linspace(-1,1, 20)
print(f(x))
[3.14159265 2.67863793 2.48074736 2.32431694 2.18823343 2.06426572
1.94810636 1.83709034 1.72935461 1.62345224 1.51814042 1.41223805
1.30450231 1.19348629 1.07732693 0.95335922 0.81727571 0.6608453
0.46295473 0. ]
1.2.6. Inproduct en Uitproduct#
Als we twee array-variabelen hebben, kunnen we het in- en uitproduct laten berekenen met behulp van ingebouwde functies: np.dot en np.cross. De namen van deze functies verwijzen naar de engelse termen voor deze producten: het dot-product(\(\cdot\)) en cross-product(\(\times\)).
a = np.array([3, 0, 1])
b = np.array([0, 2, 0])
c = np.array([4, 2, 4])
print(np.cross(a, b))
print(np.cross(a, c))
print(np.dot(a, b))
print(np.dot(a, c))
[-2 0 6]
[-2 -8 6]
0
16
Het inproduct kan genomen worden met arrays van elke lengte. Het uitproduct werkt alleen met als input een array met een lengte van 2 of 3.
1.2.7. Lengte van een vector#
Eén handige numpy-functie die je kunt gebruiken, is de norm-functie. Hiermee reken je de lengte van een vector uit. Dat is iets dat vaak handig is als je een richtingsvector (met lengte 1) wilt bepalen:
# Maak een vector 'vec' aan
vec = np.array([1, -2, 3])
print(vec)
# Bepaal de lengte van onze vector 'vec'
len_vec = np.linalg.norm(vec)
print(len_vec)
# Bepaal de richtingsvector
vec_richting = vec / len_vec
print(vec_richting)
# Check of de richtingsvector wel echt lengte 1 heeft:
print(np.linalg.norm(vec_richting))
[ 1 -2 3]
3.7416573867739413
[ 0.26726124 -0.53452248 0.80178373]
1.0