Informatique : Leçon 9. Le module numpy

  |   Source

Dans la leçon 8, on construit des matrices en les regardant comme des listes de listes, ce qui a demandé de définir toutes les opérations matricielles. Or, le module \(\texttt{numpy}\) est destiné notamment au calcul matriciel et fait le travail. On s'en servira aussi en traitement de l'image.

Une subtilité (ou un point fort) du module : les tableaux peuvent être multidimensionnels. Les matrices sont donc un cas particulier de tableaux multidimensionels.

Importation des modules

import numpy as np # importation prudente

Rappel : avec import vous importez le module. Avec as vous lui donnez un nom de préfixe pour vous rappeler les fonctions provenant du module. Autrement dit : chaque commande utilisée du module numpy est préfixée par np, ce qui permet d'identifier son origine.

Premiers pas avec numpy

La plupart des commandes suivantes sont dans votre aide-mémoire. Les matrices sont des objets de type array . Si on tape simplement :

A = [[1,0,1],[4,2,-8]]
type(A)
list

alors on obtient, comme au TP précédent, une liste de listes. En revanche, si vous déclarez votre liste comme un tableau numpy (en anglais : array) vous obtenez :

A = np.array( [[1,0,1],[4,2,-8]]) # Le préfixe np provient de l'importation
print A                          # prudente du module
[[ 1  0  1]
 [ 4  2 -8]]
type(A)
numpy.ndarray

Autrement dit, dans le module numpy, c'est la commande np.array qui permet de définir des matrices. L'objet ainsi construitn'est lus un objet de type liste, mais un objet de type tableau multidimensionnel : nd-array. C'est ce genre d'objet qui va être considéré comme une matrice à partir de maintenant.

Taille d'une matrice

Vous la récupérez avec la commande shape (c'est ce qu'on appelle une méthode au sens de la programmation orientée objet. Ce n'est pas vraiment une fonction, ni l'objet (ah ah!) de ce TP. Les méthodes se suffixent aux objets auxquelles elles appliquent, ou sur lesquelles elles opèrent) :

A.shape # C'est pourquoi on n'écrit pas shape(A) : shape est une méthode, pas une fonction
(2, 3)

Le résultat est un tuple. Ici, ce tuple contient 2 items : cela signifie que le tableau est 2-dimensionnel. Enfin, les valeurs des items nous disent que \(\mathtt{A}\) est de taille \(2 \times 3\).

Accès aux coefficients

Les doubles indices sont d'usage. Restriction habituelle de Python : les indices commencent, on s'en doute, à \(0\) :

print A
[[ 1  0  1]
 [ 4  2 -8]]

Par exemple, pour récupérer \(a_{2,3}=-8\)

A[1,2] # inutile d'utiliser A[1][2]
-8

Extraction d'une ligne ou d'une colonne

De façon plus générale on peut extraire des sous-matrices par tranches :

print A
[[ 1  0  1]
 [ 4  2 -8]]

Par exemple, si je veux \(\ell_1 =\begin{pmatrix} 1&0&1 \end{pmatrix}\), la première ligne de \(A\) :

A[0,:] # les deux points ":" servent de "joker" si vous voulez.
       # C'est l'opérateur de spécification par tranche (de slicing).
array([1, 0, 1])

**Attention. ** Vous observez qu'il n'existe plus qu'une paire de crochets : les lignes sont des tableaux 1-dimensionnels, et donc, pas des matrices au sens de tableaux 2-dimensionnels :

System Message: WARNING/2 (<string>, line 193); backlink

Inline strong start-string without end-string.
ligne = A[0,:]
print ligne
[1 0 1]
ligne.shape # La réponse ne sera pas (1,3)
            # on devrait récupérer un tuple à
            # un seul item
(3,)

On a un tuple ne contenant qu'un seul élément : on a donc un tableau \(\mathtt{1D}\) (1-dimensionnel) de longueur \(\mathtt{3}\).

Si je veux récupérer \(c_2=\begin{pmatrix} 0\\2\end{pmatrix}\), la deuxième colonne de \(\mathtt{A}\) :

A
array([[ 1,  0,  1],
       [ 4,  2, -8]])
A[:,1]
print A[:,1]
[0 2]

Ma colonne n'est pas formatée en colonne : c'est encore un tableau \(\mathtt{1D}\). Dans la suite on remédie à ce problème (si on considère que cela est un problème) grâce à une méthode permettant de redimensionner un tableau.

Redimensionner un tableau numpy

Si vous souhaitez vraiment récupérer une colonne non pas pas comme un tableau \(\mathtt{1D}\), mais une "vraie" colonne au sens des matrices, c'est-à-dire, pour l'exemple précédent, un tableau de format \((2,1)\), vous avez la méthode \(\mathtt{reshape}\) pour cela :

colonne = A[:,1]               # j'extrais la deuxième colonne de A
colonne = colonne.reshape(2,1) # avec reshape(2,1) j'en fais une matrice 2 X 1
print colonne
[[0]
 [2]]

** Exercice. ** La commande \(\mathtt{range}\) a son analogue en tableau \(\mathtt{numpy}\) : \(\mathtt{arange}\) (pour array-range). Par exemple :

np.arange(1,10) # tableau 1D des entiers de 1 à 9.
array([1, 2, 3, 4, 5, 6, 7, 8, 9])

Construire la matrice suivante : $ B =

$.

Solution.

B = np.arange(1,10).reshape(3,3)
print B
[[1 2 3]
 [4 5 6]
 [7 8 9]]

Autres opérations

Reportez-vous à l'aide-mémoire : les opérations les plus utiles y sont consignées. Voici quelques matrices typiques :

Matrices remarquables

Matrices de 1's

atilla = np.ones([3,3])
print atilla
[[ 1.  1.  1.]
 [ 1.  1.  1.]
 [ 1.  1.  1.]]

Matrices de 0's

nulle = np.zeros([3,3])
print nulle
[[ 0.  0.  0.]
 [ 0.  0.  0.]
 [ 0.  0.  0.]]

Matrice unité ou identité

identite = np.eye(4) #  Matrice I4 : identité d'ordre 4
print identite,"\n"  # rappel : "\n" est le saut de ligne
print 3*identite     # une matrice scalaire
[[ 1.  0.  0.  0.]
 [ 0.  1.  0.  0.]
 [ 0.  0.  1.  0.]
 [ 0.  0.  0.  1.]]

[[ 3.  0.  0.  0.]
 [ 0.  3.  0.  0.]
 [ 0.  0.  3.  0.]
 [ 0.  0.  0.  3.]]

Une remarque sur le produit matriciel

En Python, vous pouvez faire deux types de produit :

  1. Le produit matriciel que vous connaissez avec les restrictions de format que cela implique. La commande est :

    \begin{equation*} \texttt{np.dot(A,B)}\quad \text{, et ce n'est pas }\quad \texttt{A*B} \end{equation*}
  2. Il y a un autre produit qui existe (mais qui ne correspond à rien en maths) : le produit élément par élément (broadcasting). Pour deux matrices \(A\) et \(B\) de même format :

\begin{equation*} \texttt{A*B} \end{equation*}

donne la matrice de même format que \(A\) et \(B\) de coefficient général \(a_{i,j} \times b_{i,j}\). Opération très utile pour le calcul en "parallèle" (évite le recours à une boucle).

Exercice

  1. Calculer \(A^2\)\(A\) est la matrice Attila d'ordre 3.
  2. Construire en utilisant la matrice \(B\) précédente la matrice \(C\) suivante :

$ C =

$

# Réponse à 1.  :
#----------------
A = np.ones([3,3])
np.dot(A,A) #Produit matriciel de A avec A
array([[ 3.,  3.,  3.],
       [ 3.,  3.,  3.],
       [ 3.,  3.,  3.]])
# Réponse à 2. :
#---------------
B = np.arange(1,10).reshape(3,3)
print 'B ='
print B                         # la matrice B de tout à l'heure
M = np.array([2**k for k in B]) # construction en compréhension
print 'M = '
print M
C = B*M                         # la matrice  est le produit
print 'C = '                    # élément par élement de B et M
print C
B =
[[1 2 3]
 [4 5 6]
 [7 8 9]]
M =
[[  2   4   8]
 [ 16  32  64]
 [128 256 512]]
C =
[[   2    8   24]
 [  64  160  384]
 [ 896 2048 4608]]
Comments powered by Disqus
Partager