La vectorisation¶
Vous allez apprendre à tirer le meilleur parti de Python
associé avec numpy
en utilisant des fonctions préprogrammées qui traitent les vecteurs ou les matrices globalement. C’est ce que l’on appelle la "vectorisation".
Rappel sur les extractions d'élements :¶
Je crée une matrice C 4x5 qui est la matrice de VanderMonde, il existe une fonction toute faite pour cela dans numpy
. Le détail de la matrice importe peu pour ce cours (plus d'informations sur cette matrice dans votre cours de mathématiques ou bien sur wikipedia)
import numpy as np
C = np.vander([1,2,3,5], 5,increasing=True)
print(C)
On peut extraire une sous-matrice de C en utilisant les deux points ":" comme nous l'avons déjà vu lors de l'introduction à Numpy. Il est aussi possible d'imposer le pas avec la syntaxe debut:fin:pas
exemple 2:11:2 prendra les éléments entre le "piquet" 2 et le "piquet" 11 avec un pas de 2.
print("Extraction de C \n",C[0:3,1:3]) # Extrait entre le piquet 0 et le piquet 3 pour le premier indice
# et du piquet 1 au piquet 3 pour le deuxième indice.
# ce qui correspond aux lignes 1, 2 et 3 et aux colonnes 2 et 3 de la matrice
print('Lignes et colonnes paires :\n',C[0:4:2,0:5:2]) # On impose un pas de 2
Il est aussi utile de se servir de -1, -2, -3, ... comme indices pour compter à partir de l'indice de fin du tableau. On peut aussi ne rien mettre pour désigner le début ou la fin.
print(C[1:-1,:]) # Extrait du deuxième à l'avant dernier élément pour le premier indice (les lignes) "1:-1"
# et tous les éléments pour le deuxième indice (les colonnes) avec ":"
C[:-2,1:] # On part de 0 et on s'arrète à -2 de la fin pour le premier indice
# et on part de 1 jusqu'à la fin pour le deuxième indice.
Ce schéma extrait des lectures notes de Scipy illustre bien les diverses possibilités:
Tableaux : dimensions, notion d'axe, taille, nombre d'éléments¶
La fonction np.ndim
permet de connaitre le nombre de dimensions du tableau. 1 pour un vecteur, 2 pour une matrice.
print("Nb de dimensions de C : ", np.ndim(C))
On introduit maintenant la notion d'axe de la matrice. L'axe 0 désigne la direction suivant le premier indice (de haut en bas), l'axe 1 la direction en faisant varier le deuxième indice (de gauche à droite).
A l'aide de la fonction np.size
, il est possible d'obtenir le nombre total d'éléments d'une matrice,
ou le nombre d'élements suivant un des axes.
print("Nb total d'éléments : ", np.size(C))
print("Nb d'éléments suivant l'axe 0 : ", np.size(C,axis=0))
print("Nb d'éléments suivant l'axe 1 : ", np.size(C,1)) # On peut omettre le 'axis ='
A l'aide de la fonction np.shape
, il est possible d'obtenir le nombre d'éléments dans chaque dimension d'un tableau. Par abus de langage, on va dire que l'on obtient les dimensions du tableau. np.shape
renvoie un tuple
.
print("Les dimensions du tableau C sont : ", np.shape(C))
print("C'est aussi équivalent d'utiliser la syntaxe : ", C.shape )
Manipulations de matrices.¶
Il existe dans numpy
de nombreuses fonctions qui manipulent les tableaux. Il y a des fonctions inspirées des mathématiques comme la transposée mais aussi des fonctions comme rot90
, flipud
, fliplr
(ud: veut dire Upside Down, lr: Left Right).
Pour plus d'information sur une fonction faire help(fonction). Par exemple help(np.rot90)
np.transpose(C) # qui peut aussi s'écrire C.transpose() ou en raccourci C.T
np.flipud(C) # ou encore np.flip(C,axis=0) ou en raccourci np.flip(C,0) 0 désigne
# l'axe à choisir pour le flip
np.fliplr(C) # ou encore np.flip(C,1) ou np.flip(C,axis=1)
np.rot90(C) # tourne la matrice de 90 degrés dans le sens trigo.
Il est possible de réorganiser les éléments de la matrices avec la fonction np.reshape
. Bien évidement le nombre d'éléments doit être égal au produit du nombre d'éléments dans chaque dimension (il y a 20 éléments dans notre exemple pour C on ne peut donc faire que (1,20) ou (2,10) ou (4,5) ou (5,4) ou (10,2) ou (20,1)... ).
print("C= \n",C)
print("C en matrice avec 10 lignes et 2 colonnes :\n", np.reshape(C,(10,2)))
Fonctions préprogrammées, opérations simples¶
Dans numpy
, en plus de la fonction np.zeros
qui permet de créer un tableau de zéros, il existe son équivalent avec 1 np.ones
. Deux autres fonctions peuvent être pratiques en algèbre linéaire np.eye
et np.diag
print(" Matrice 3x3 de 1 \n",np.ones((3,3))) # Notez l'utilisation du tuple (3,3)
print(" Matrice identité 3x3 \n",np.eye(3)) # 3 est l'argument
print(" Matrice diagonale \n",np.diag([3.,4.,-1.,6.])) # le vecteur diagonal est l'argument
# la dimension de la matrice (carrée) s'adapte
On crée deux matrices A et B afin de faire des opérations simples ou préprogrammées
- A est une matrice nxn d'entiers allant de 1 à n² dont la somme des lignes, des colonnes et de la diagonale donnent la même valeur.
- B est une matrice nxn d'entiers tirés aléatoirement entre 1 à n².
On prend ici n=3.
A = np.array([[8,1,6],[3,5,7],[4,9,2]])
B = np.random.randint(1,10, size=(3, 3))
print("A = \n",A)
print("B = \n",B)
Comme nous l'avons déjà vu, de manière assez intuitive et naturelle, on peut utiliser les opérateurs classiques d'addition, soustraction, division ou la multiplication entre A et B
A + B
donne bien le résultat prévu sachant que A et B sont conformants (ici les deux matrices sont de tailles 3x3).
Derrière cette opération banale, il y a bien des boucles for
qui sont réalisées de manière interne en parcourant chaque élément des tableaux. Ces opérations sont masquées et elles sont optimisées par python pour vous. En python, on évite autant que possible de coder soi même des boucles.
- Il existe de nombreuses fonctions préprogrammées en numpy. Prenons par exemple
np.sum
que l'on a déjà vu pour un vecteur.
np.sum(A) # fait la somme de tous les éléments de A.
np.sum(A,0) # renvoie un vecteur qui est la somme suivant l'axe 0
# c-à-d la somme de chaque colonne 8+3+4,1+5+9,6+7+2
np.sum(A,1) # renvoie un vecteur qui est la somme suivant l'axe 1 c-à-d la somme de chaque ligne
np.diag(A) # renvoie un vecteur contenant les éléments de la diagonale de A
np.sum(np.diag(A)) # enchainant les deux fonctions on obtient la somme des éléments de la diagonale de A
Les fonctions np.min
, np.max
, np.mean
(la moyenne) fonctionnent exactement sur le même principe que np.sum
.
Pour le max (ou le min), la fonction np.argmax (np.argmin) renvoie l'indice du max.