Professional Documents
Culture Documents
adapté du travail de J.R. Johansson (robert@riken.jp) http://dml.riken.jp/~rob/ In [6]: # un vecteur: l'argument de la fonction est une liste Python
v = array([1,2,3,4])
In [3]: # et JUSTE POUR MOI (pour avoir les figures dans le notebook) print v
%pylab inline
[1 2 3 4]
Welcome to pylab, a matplotlib-based Python environment [backend:
module://IPython.zmq.pylab.backend_inline]. On peut alors visualiser ces données :
For more information, type 'help(pylab)'.
In [7]: figure()
plot(v,'r')
Introduction xlabel('x')
ylabel('v')
title('Exemple simple')
show()
numpy est un module utilisé dans presque tous les projets de calcul numérique sous Python
Il fournit des structures de données performantes pour la manipulation de vecteurs, matrices et
tenseurs plus généraux
numpy est écrit en C et en Fortran d'où ses performances élevées lorsque les calculs sont vectorisés
(formulés comme des opérations sur des vecteurs/matrices)
Arrays numpy Les objets v et M sont tous deux du type ndarray (fourni par numpy)
Dans la terminologie numpy, vecteurs, matrices et autres tenseurs sont appelés arrays. In [9]: type(v), type(M)
Out[10]: (4,) Autres types possibles avec dtype : int, float, complex, bool, object, etc.
On peut aussi spécifier la précision en bits: int64, int16, float128, complex128.
In [11]: M.shape
Out[13]: (2, 2)
In [19]: x = arange(-1, 1, 0.1)
Les arrays ont un type qu'on obtient via dtype:
x
In [16]: a = array([1,2,3])
a[0] = 3.2 In [21]: print e
print a print logspace(0, 10, 10, base=e)
a.dtype 2.71828182846
[3 2 3] [ 1.00000000e+00 3.03773178e+00 9.22781435e+00 2.80316249e+01
8.51525577e+01 2.58670631e+02 7.85771994e+02 2.38696456e+03
Out[16]: dtype('int32') 7.25095809e+03 2.20264658e+04]
On peut définir le type de manière explicite en utilisant le mot clé dtype en argument: mgrid
In [24]: y
Données aléatoires
diag
In [25]: from numpy import random
In [29]: # une matrice diagonale
In [26]: # tirage uniforme dans [0,1] diag([1,2,3])
random.rand(5,5)
Out[29]: array([[1, 0, 0],
Out[26]: array([[ 0.9233761 , 0.42880142, 0.58351343, 0.12834447, [0, 2, 0],
0.17716305], [0, 0, 3]])
[ 0.31042569, 0.56215271, 0.0380865 , 0.8392456 ,
0.06301622], In [30]: # diagonale avec décalage par rapport à la diagonale principale
[ 0.04295119, 0.29258217, 0.71466429, 0.41924466, diag([1,2,3], k=1)
0.73821216],
[ 0.36466787, 0.18688405, 0.17281408, 0.96626847, Out[30]: array([[0, 1, 0, 0],
0.54234518], [0, 0, 2, 0],
[ 0.6851275 , 0.64834141, 0.33608157, 0.09813496, [0, 0, 0, 3],
0.06831042]]) [0, 0, 0, 0]])
Out[28]: (array([ 8, 34, 87, 152, 200, 218, 160, 88, 35, 18]),
Fichiers séparés par des virgules (CSV)
array([-2.87253254, -2.31280465, -1.75307676, -1.19334887,
-0.63362098, Un format fichier classique est le format CSV (comma-separated values), ou bien TSV (tab-separated values).
-0.07389309, 0.4858348 , 1.04556269, 1.60529058, 2.16501847, Pour lire de tels fichiers utilisez numpy.genfromtxt. Par exemple:
2.72474636]),
<a list of 10 Patch objects>)
In [33]: data = genfromtxt('data.csv', delimiter=',')
data
Out[33]: array([[ 1., 2., 3., 4., 5.],
[ 6., 7., 8., 9., 10.], Autres propriétés des arrays numpy
[ 1., 3., 3., 4., 6.],
[ 1., 2., 3., 4., 20.]])
In [41]: M.itemsize # octets par élément
In [34]: data.shape
Out[41]: 8
Out[34]: (4, 5)
3.206577386307648547e-01 3.560027430397629811e-01 In [44]: # v est un vecteur, il n'a qu'une seule dimension -> un seul indice
9.333794526422668492e-01 v[0]
1.560657844009143425e-01 5.237993704258564476e-01
2.857153341794410606e-01 Out[44]: 1
3.359966948652352015e-01 4.612427499341457127e-01
9.431427012755255745e-02
In [45]: # M est une matrice, ou un array à 2 dimensions -> deux indices
M[1,1]
In [38]: savetxt("random-matrix.csv", M, fmt='%.5f', delimiter=',') # fmt
spécifie le format
Out[45]: 0.52379937042585645
!cat random-matrix.csv
#!type random-matrix.csv Contenu complet :
0.32066,0.35600,0.93338 In [46]: M
0.15607,0.52380,0.28572
0.33600,0.46124,0.09431 Out[46]: array([[ 0.32065774, 0.35600274, 0.93337945],
[ 0.15606578, 0.52379937, 0.28571533],
[ 0.33599669, 0.46124275, 0.09431427]])
Format de fichier Numpy natif
Pour sauvegarder et recharger des array numpy : numpy.save et numpy.load : La deuxième ligne :
Out[53]: array([[ 1. , 0.35600274, -1. ], Le slicing fonctionne de façon similaire pour les array multi-dimensionnels
[ 0. , 0. , -1. ],
[ 0.33599669, 0.46124275, -1. ]])
In [64]: A = array([[n+m*10 for n in range(5)] for m in range(5)])
A
Slicing ou accès par tranches
Out[64]: array([[ 0, 1, 2, 3, 4],
Slicing fait référence à la syntaxe M[start:stop:step] pour extraire une partie d'un array : [10, 11, 12, 13, 14],
[20, 21, 22, 23, 24],
In [54]: A = array([1,2,3,4,5]) [30, 31, 32, 33, 34],
A [40, 41, 42, 43, 44]])
Extraction de données à partir d'arrays et création d'arrays In [77]: take([-3, -2, -1, 0, 1, 2], row_indices)
Out[77]: array([-2, 0, 2])
In [89]: A * 2, A + 2
choose
Construire un array en selectionnant des éléments dans d'autres arrays :
Out[89]: (array([[ 0, 2, 4, 6, 8],
[20, 22, 24, 0, 0],
In [78]: which = [1, 0, 1, 0]
[40, 42, 44, 0, 0],
choices = [[-2,-2,-2,-2], [5,5,5,5]]
[60, 62, 64, 66, 68],
[80, 82, 84, 86, 88]]),
choose(which, choices)
array([[ 2, 3, 4, 5, 6],
[12, 13, 14, 2, 2],
Out[78]: array([ 5, -2, 5, -2]) [22, 23, 24, 2, 2],
[32, 33, 34, 35, 36],
[42, 43, 44, 45, 46]]))
Algèbre linéaire
La performance des programmes écrit en Python/Numpy dépend de la capacité à vectoriser les calculs (les Visualiser des matrices
écrire comme des opérations sur des vecteurs/matrices) en évitant au maximum les boucles for/while
In [90]: C = random.rand(300,200)
Opérations scalaires figure()
On peut effectuer les opérations arithmétiques habituelles pour multiplier, additionner, soustraire et diviser des imshow(C)
arrays avec/par des scalaires : colorbar()
show()
In [85]: v1 = arange(0, 5)
In [86]: v1 * 2
In [87]: v1 + 2
In [88]: figure()
subplot(1,2,1)
plot(v1 ** 2,'g--', label='$y = x^2$')
legend(loc=0)
subplot(1,2,2)
plot(sqrt(v1), 'r*-', label='$y = \sqrt{x}$')
legend(loc=2)
show() Opérations terme-à-terme sur les arrays
Les opérations par défaut sont des opérations terme-à-terme :
In [92]: v1 * v1
[[ 0 1 2 3 4] In [98]: M = matrix(A)
[10 11 12 0 0] v = matrix(v1).T # en faire un vecteur colonne
[20 21 22 0 0]
[30 31 32 33 34] In [103]: v, v.T
[40 41 42 43 44]]
[0 1 2 3 4] Out[103]: (matrix([[0],
Out[94]: array([[ 0, 1, 4, 9, 16], [1],
[ 0, 11, 24, 0, 0], [2],
[ 0, 21, 44, 0, 0], [3],
[ 0, 31, 64, 99, 136], [4]]),
[ 0, 41, 84, 129, 176]]) matrix([[0, 1, 2, 3, 4]]))
Out[99]: ((5, 5), (6, 1)) In [105]: imag(C) # same as: C.imag
Voir également les fonctions : inner, outer, cross, kron, tensordot. Utiliser par exemple help(kron).
Analyse de données
Transformations d'arrays ou de matrices Numpy propose des fonctions pour calculer certaines statistiques des données stockées dans des arrays :
In [136]: data[:,2].min()
Calculs avec parties d'arrays
Out[136]: 1 en utilisant l'indexation ou n'importe quelle méthode d'extraction de donnés à partir des arrays
Out[138]: 10
In [121]: unique(data[:,1])
Out[139]: 24
In [122]: mask = data[:,1] == 2
sum, prod, et trace
In [123]: mean(data[mask,3])
In [113]: d = arange(0, 10)
d Out[123]: 4.0
B
In [156]: # changer B affecte A
B[0,0] = 10
Out[138]: array([[5, 5, 5, 5]])
B
B
In [141]: B[0:5] = 10
Out[160]: array([[-5, 2], B
[ 3, 4]])
Out[141]: array([10, 10, 10, 10])
par exemple pour convertir un vecteur en une matrice ligne ou colonne : concatenate
hstack et vstack
In [146]: v[:,newaxis].shape
Out[147]: (1, 3)
In [156]: hstack((a,b.T))
repeat et tile
Itérer sur les éléments d'un array
Dans la mesure du possible, il faut éviter l'itération sur les éléments d'un array : c'est beaucoup plus
In [148]: a = array([[1, 2], [3, 4]]) lent que les opérations vectorisées
a Mais il arrive que l'on n'ait pas le choix...
1
Out[149]: array([1, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 4]) 2
3
In [150]: # on peut spécifier l'argument axis 4
repeat(a, 3, axis=1)
In [158]: M = array([[1,2], [3,4]])
Out[150]: array([[1, 1, 1, 2, 2, 2],
[3, 3, 3, 4, 4, 4]]) for row in M:
print "row", row ----> 1 theta(array([-3,-2,-1,0,1,2,3]))
row_idx 0 row [1 2] Pour améliorer les performances, il vaut mieux concevoir dès le départ la fonction de sorte qu'elle accepte
col_idx 0 element 1 des vecteurs en entrée :
col_idx 1 element 2
row_idx 1 row [3 4]
In [165]: def theta(x):
col_idx 0 element 3
"""
col_idx 1 element 4
Vector-aware implementation of the Heaviside step function.
"""
In [160]: # chaque élément de M a maintenant été élevé au carré return 1 * (x >= 0)
M
In [162]: theta(array([-3,-2,-1,0,1,2,3]))
In [169]: if (M > 5).any():
----------------------------------------------------------------------- print "au moins un élément de M est plus grand que 5"
---- else:
ValueError Traceback (most recent call print "aucun élément de M n'est plus grand que 5"
last) au moins un élément de M est plus grand que 5
<ipython-input-162-28c6d794452f> in <module>()
In [170]: if (M > 5).all():
print "tous les éléments de M sont plus grands que 5"
else:
print "tous les éléments de M sont plus petits que 5"
Type casting
On peut créer une vue d'un autre type que l'original pour un array
Out[171]: dtype('int32')
In [172]: M2 = M.astype(float)
M2
In [173]: M2.dtype
Out[173]: dtype('float64')
In [174]: M3 = M.astype(bool)
M3
In []: