Numpy et calcul matriciel
Numpy et calcul matriciel
Création de Matrices
Le type de base de la bibliothèque Numpy est le ndarray (N-dimensionnal array) : Tableau à N dimensions (1D, 2D, 3D, … )
- ndarray 1D : en python, le type de base liste correspond à un nd-array 1D mais les calculs avec le type ndarray sont plus rapides.
- ndarray 2D peut être représenté comme un tableau dans un tableur
- ndarray 3D ( ex : image couleur RGB )
L’attribut shape ( dimensions ) :
- ndim = 1 => shape = (2,) => 2 lignes
- ndim = 2 => shape = (2,3) => 2 lignes 2 colonnes
- ndim = 3 => shape = (2,3,3) => 2 lignes 2 colonnes 3 profondeurs
REMARQUE : shape est un tuple ( liste constante ), shape[0]=2 : chaque élément de shape est une constante
import numpy as np
tableau = np.array([1,2,3]) # creation de l'objet tableau, appartenant à la classe numpy
print(tableau.size)
3
# Dimensions du tableau : shape est un ATTRIBUT de l'OBJET tableau appartenant à la CLASSE numpy
tableau.shape
(3,)
# Nombre d'éléments dans le tableau
tableau.size
3
tab_2d_23 = np.array( [[1,2,3], [4,5,6]] ) # 2 lignes ( 0 1 ) 3 colonnes ( 0 1 2 )
print(tab_2d_23.shape)
tab_2d_23
(2, 3)
array([[1, 2, 3],
[4, 5, 6]])
tab_2d_32 = np.array( [[1,2], [3,4] , [5,6]] ) # 3 lignes ( 0 1 2 ) 2 colonnes ( 0 1 )
print(tab_2d_32.shape)
tab_2d_32
(3, 2)
array([[1, 2],
[3, 4],
[5, 6]])
# accès aux éléments du tableau
print(tab_2d_32[0,1]) # attention le premier élément est à l'index 0
2
# Matrice de 1
A = np.ones((4,2))
print('A =\n',A)
A =
[[1. 1.]
[1. 1.]
[1. 1.]
[1. 1.]]
Concatenation / Redisposition
A = np.zeros((4,2))
B = np.ones((4,2))
print('A =\n',A)
print('B =\n',B)
A =
[[0. 0.]
[0. 0.]
[0. 0.]
[0. 0.]]
B =
[[1. 1.]
[1. 1.]
[1. 1.]
[1. 1.]]
# horizontal stack : on colle côte à côte
C = np.hstack((A,B))
# équivalent à :
C = np.concatenate((A,B), axis=1) # axis 0 : axe vertical, axis 1 : axe horizontal
print(C.shape)
C
(4, 4)
array([[0., 0., 1., 1.],
[0., 0., 1., 1.],
[0., 0., 1., 1.],
[0., 0., 1., 1.]])
D = np.vstack((A,B))
# équivalent à :
D = np.concatenate((A,B), axis=0)
print(D.shape)
D
(8, 2)
array([[0., 0.],
[0., 0.],
[0., 0.],
[0., 0.],
[1., 1.],
[1., 1.],
[1., 1.],
[1., 1.]])
D = D.reshape((4,4)) # redisposition, il faut le même nombre d'éléments
D
array([[0., 0., 0., 0.],
[0., 0., 0., 0.],
[1., 1., 1., 1.],
[1., 1., 1., 1.]])
A=np.array([1,2,3])
A.shape
(3,)
A = A.reshape((A.shape[0],1)) # --> forçage à un shape (x,1) pour nd=1, nécessaire pour certains calculs
A.shape
(3, 1)
A = A.squeeze() # --> forçage à un shape (x,)
A.shape
(3,)
D = D.ravel() # --> On écrase tout sur une seule ligne
D
array([0., 0., 0., 0., 0., 0., 0., 0., 1., 1., 1., 1., 1., 1., 1., 1.])
Indexing / Slicing / Masking
# 2D array ; axe 0 : lignes ; axe 1 : colonnes
A = np.array([[1,2,3],[4,5,6],[7,8,9]])
print(A)
[[1 2 3]
[4 5 6]
[7 8 9]]
print(A[0,0])
print(A[1,2])
1
6
# Slicing
col = A[:,0] # Colonne 0 : on prend tout
col
array([1, 4, 7])
lin = A[0,:] # ligne 0 : on prend tout
lin
array([1, 2, 3])
B = A[0:2,0:2] # lignes 0 à 2 ( 2 exclue ), colonnes 0 à 2 ( 2 exclue )
B
array([[1, 2],
[4, 5]])
A[0:2,0:2] = 10
A
array([[10, 10, 3],
[10, 10, 6],
[ 7, 8, 9]])
A[:,-2:] # affichage 2 dernières colonnes
array([[10, 3],
[10, 6],
[ 8, 9]])
C = np.zeros((5,5))
C[::2,::2] = 1 # toutes les valeurs avec un pas de 2
C
array([[1., 0., 1., 0., 1.],
[0., 0., 0., 0., 0.],
[1., 0., 1., 0., 1.],
[0., 0., 0., 0., 0.],
[1., 0., 1., 0., 1.]])
# Masquage ( Boolean Indexing )
A = np.random.randint(0,10,[5,5])
print(A)
print(A.shape)
print(A < 5)
[[3 4 6 5 6]
[5 9 5 4 1]
[6 7 4 5 6]
[8 6 7 9 5]
[4 8 6 9 9]]
(5, 5)
[[ True True False False False]
[False False False True True]
[False False True False False]
[False False False False False]
[ True False False False False]]
A[A<5]=123 # tous les nombres inférieurs à 5 deviennent 10
A
array([[123, 123, 6, 5, 6],
[ 5, 9, 5, 123, 123],
[ 6, 7, 123, 5, 6],
[ 8, 6, 7, 9, 5],
[123, 8, 6, 9, 9]])
# filtrage :
A_filtered = A[A<9]
print(A_filtered)
print(A_filtered.shape)
[6 5 6 5 5 6 7 5 6 8 6 7 5 8 6]
(15,)
Opération sur les éléments des tableaux
A = np.random.seed(0)
A = np.random.randint(-10,10,[2,3])
print(A)
[[ 2 5 -10]
[ -7 -7 -3]]
# somme de tous les éléments du tableau
s = A.sum()
s
-20
# somme des colonnes
s= A.sum(axis=0) # axe 0 = VERTICAL ; axe 1 = axe HORIZONTAL
s
array([ -5, -2, -13])
# somme cumulée
s = A.cumsum()
s
array([ 2, 7, -3, -10, -17, -20])
# position du minimum
A.argmin( axis=0 ) # POSITION du minimum pour chaque colonne
array([1, 1, 0])
A.argsort( axis=1 ) # retourne les index dans l'ordre de tri
# du tableau, sans modifier le tableau
array([[2, 0, 1],
[0, 1, 2]])
A.sort( axis=1 ) # tri --> A est modifié
A
array([[-10, 2, 5],
[ -7, -7, -3]])
np.exp(A) # exponentielle pour chaque nombre
array([[4.53999298e-05, 7.38905610e+00, 1.48413159e+02],
[9.11881966e-04, 9.11881966e-04, 4.97870684e-02]])
Statistiques
A.min()
-10
A.max()
5
# Moyenne
A.mean()
-3.3333333333333335
A.mean(axis = 0) # Moyenne sur chaque colonne
array([-8.5, -2.5, 1. ])
A.std() # ecart type
5.312459150169743
A.var() # variance
28.222222222222225
np.corrcoef(A) # corrélation entre différentes lignes et colonnes
array([[1. , 0.65465367],
[0.65465367, 1. ]])
values, counts = np.unique(A,return_counts=True) # nombre d'occurences dans un tableau
print( values, counts )
[-10 -7 -3 2 5] [1 2 1 1 1]
# NaN corrections
A = np.random.randn(5,5)
A[0,3]=np.nan
A[4,4]=np.nan
A
array([[ 1.86755799, -0.97727788, 0.95008842, nan, -0.10321885],
[ 0.4105985 , 0.14404357, 1.45427351, 0.76103773, 0.12167502],
[ 0.44386323, 0.33367433, 1.49407907, -0.20515826, 0.3130677 ],
[-0.85409574, -2.55298982, 0.6536186 , 0.8644362 , -0.74216502],
[ 2.26975462, -1.45436567, 0.04575852, -0.18718385, nan]])
# Calcul de la moyenne sans considérer les nan
np.nanmean(A)
0.21961182192574394
# compter le nombre de nan :
np.isnan(A) # masque booleen
np.isnan(A).sum()/A.size # taux de nan dans le tableau
0.08
A[np.isnan(A)] = 0 # 0 remplace nan
A
array([[ 1.86755799, -0.97727788, 0.95008842, 0. , -0.10321885],
[ 0.4105985 , 0.14404357, 1.45427351, 0.76103773, 0.12167502],
[ 0.44386323, 0.33367433, 1.49407907, -0.20515826, 0.3130677 ],
[-0.85409574, -2.55298982, 0.6536186 , 0.8644362 , -0.74216502],
[ 2.26975462, -1.45436567, 0.04575852, -0.18718385, 0. ]])
Calcul Matriciel
# Algèbre linéaire linalg
A = np.ones((2,3))
B = np.ones((3,2))
print('A=\n', A)
print('B=\n', B)
A=
[[1. 1. 1.]
[1. 1. 1.]]
B=
[[1. 1.]
[1. 1.]
[1. 1.]]
A.T # Transpose matrice
array([[1., 1.],
[1., 1.],
[1., 1.]])
res = A.dot(B) # Produit matriciel (2,3)*(3,2)=(2,2)
res
array([[3., 3.],
[3., 3.]])