contenu de ce notebook (sauter si déjà acquis)¶
- la vectorisation (appliquer une fonction à tout un tableau sans passer par un
for-python
) - les
ufunc
numpy.vectorize
# on importe la librairie numpy
import numpy as np
from matplotlib import pyplot as plt
qu’est-ce que la vectorisation ?¶
%%timeit
n = 1000000
x = np.linspace(0, 2*np.pi, n)
# la bonne façon
np.sin(x) # np.sin appliquée au tableau x
65 ms ± 19.5 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)
# pour comparer les choses comparables
import math
%%timeit
n = 1000000
x = np.linspace(0, 2*np.pi, n)
# la mauvaise façon
for e in x: # une boucle for sur un tableau numpy
# c'est toujours une mauvaise idée
math.sin(e)
538 ms ± 156 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
dans une première version de ce notebook, pour cette deuxième - et mauvaise - façon de faire on avait artificiellement forcé le trait car:
- on avait utilisé
np.sin
au lieu demath.sin
; merci à Damien Corral qui a remarqué quenp.sin
appliqué à un scalaire Python ajoute une inefficacité ! - et de plus on rangeait les résultats dans une liste, ce qui aggrave encore les écarts
après ces corrections, qui permettent de mieux isoler la perte d’efficacité, on observe toujours un rapport de 1 à 10 ! (et en plus on ne garde même pas les résultats du calcul)
dessiner un cercle de rayon r
¶
exercice
Dessinez un cercle de rayon r
indices
avec θ variant de 0 à- si votre cercle apparaît elliptique, c’est que les échelles de vos axes diffèrent
demandez à ce qu’elles soient égales avecplt.axis('equal')
# votre code
calculer une fonction polynomiale¶
exercice
faites une fonction qui retourne le calcul d’un polynome
par exemple
(puissance:**
ounp.power
)appliquez la directement à un
np.ndarray
(sans faire defor
) qu’obtenez-vous en retour ?tracez la courbe de la fonction
# votre code ici
def scalar_function(x):
pass
les ufunc
¶
qu’est-ce qu’une ufunc
¶
Le mécanisme général qui applique une fonction à un tableau
est connu sous le terme de Universal function - ou encore ufunc
En conclusion, vous devez toujours utiliser les ufunc
et plus jamais les for-python
- même si ça vous paraît plus difficile
- même si vous utilisiez des
for-python
en prépa - par souci de la performance en temps, et de propreté de votre code, vous ne pouvez plus y échapper
Une habitude à prendre:
- c’est juste une autre manière de penser le code
- vos codes seront compacts et lisibles (élégants)
Souvenez-vous du terme ufunc
car c’est utile pour des recherches sur Internet
quelles sont les fonctions vectorisées ?¶
les opérateurs arithmétiques classiques
et leur contre-partie numpy
(Ufuncs)
opérateur | numpy fonction |
---|---|
+ | np.add |
- | np.substract |
* | np.multiply |
/ | np.divide |
// | np.floor_divide |
\% | np.mod |
** | np.power |
les fonctions de comparaison, trigonométriques...
fonction | numpy fonction |
---|---|
comparaison | np.greater , np.less , np.equal , ... |
valeur absolue | np.absolute or np.abs |
trigonometrie | np.sin , np.cos , ... |
exponentielle | np.exp , np.exp2 , .. |
logarithme | np.log , np.log2 , np.log10 |
vous allez les utiliser sans même vous en rendre compte !
savoir si une fonction est une ufunc
¶
demandez-le lui
np.add
<ufunc 'add'>
numpy.add
en est !
# essayez !
np.power
<ufunc 'power'>
pour vectoriser une fonction¶
exercice
le but du jeu ici c’est de voir comment vectoriser une fonction que vous écrivez vous
on s’interdit donc, dans cet exercice, d’utiliser des fonctions de numpy
, ni la fonction builtin abs
de Python
si vous préférez, vous pouvez choisir d’implémenter une fonction définie par morceaux
genre sur les nombres négatifs et sur les positifs
- écrivez une fonction qui calcule la valeur absolue d’un scalaire x
absolute(x)
- testez votre fonction sur des scalaires
- créez un
np.ndarray
de scalaires et appliquez-lui la fonction - que se passe-t-il ?
# votre code ici