On commence par charger la biblithèque numpy sous l'espace de nom réduit np. Toutes les classes et les fonctions sont alors préfixées par np..
import numpy as np
Le type qui va nous intéresser est array. Il permet de représenter les vecteurs.
v = np.array( [1., 2., 3.] ) # construction à partir d'une liste
print(v) # affichage différent d'une liste
v # c'est un array, et pas une liste basique Python
On peut récupérer la taille d'un vecteur grâce à la fonction len(), ou grâce à la fonction shape() qui donne en réalité les dimensions d'une quantité de type array (plusieurs dimensions correspondant à une imbrication d'array, utile notamment pour représenter des matrices).
print( "Le vecteur v est de taille", len(v), ".")
print(np.shape(v))
n, = np.shape(v) # v est un vecteur, donc seule la première dimension nous intéresse
print ("Il contient donc ", n, " éléments.")
print("matrice")
a = np.zeros(shape=(3,3)) # matrice 3x3
a[1,2] = 1
print(a)
print("tenseur")
a = np.zeros(shape=(2,2,2)) # tenseur à 3 indices
a[0,1,1] = 2
print(a)
La manipulation des quantités de type array est similaire à celle des listes Python.
v = np.arange(1, 15, 2) # nombres impairs de 1 à 14 : arange() au lieu de range()
print(v)
v[0] = 100
print(v[:2], v[3:5])
Comme pour les listes, il faut faire attention lorsqu'on utilise les affectations, car il y a partage des données. Pour faire une vraie copie, il faut le demander explicitement.
u = np.array([1,2,3])
v = u
w = u.copy()
print(v)
print(w)
print()
u[2] = 100 # modifie u, ainsi que v qui est juste un alias pour u.
print(v)
print(w)
Contrairement à range(), la fonction arange() accepte des nombres flottants en arguments.
v = np.arange(0., 2., 0.3)
print(v)
De plus, il existe la fonction linspace() qui prend en entrée a, b et n, et qui renvoie un array avec n valeurs allant de a à b et régulièrement espacées.
print(np.linspace(0, 1, 9))
print(np.linspace(0, np.pi, 10))
Les opérations sur les scalaires s'entendent de façon naturelle lorsqu'un des arguments est de type array. L'opération est alors appliqué à chaque élément du vecteur.
print(v)
print(10 * v)
print(np.sqrt(v))
Si on dispose de deux quantités de type array, on peut aussi faire la somme ou le produit coefficient par coefficient grâces aux opérateurs + et * . Attention toutefois à appliquer ces opérations sur des vecteurs de même taille uniquement.
u = np.array( [2., 2., 2., 2., 2., 2., 2.] )
print(u)
print(v)
print()
print(u + v)
print(u * v) # note : ceci est équivalent à 2 * v
u = np.array( [1., 2., 3.] )
u + v # erreur, les tailles de u et v sont différentes
Enfin, on dispose de beaucoup de fonctions utiles. Consulter la documentation
print(v)
print("La moyenne des éléments de v est", np.mean(v))
print("De plus, l'écart type est de ", np.std(v))
Voyons maintenant comme définir et manipuler des matrices. La définition peut se faire via le constructeur array(), en donnant cette fois une liste de listes en arguments.
m = np.array( [[1, 2, 3],
[4, 5, 6]])
print(m)
Notez que la variable m ainsi définie est en réalité une quantité de type array contenant des valeurs elles-même de type array.
m[0] # première ligne de la matrice
La fonction len() nous permet de récupérer le nombre de lignes de la matrice.
len(m)
La fonction shape() va, elle, nous renvoyer un couple d'entier, nous permettant ainsi de récupérer les dimensions de notre matrice.
np.shape(m)
Il existe quelques fonctions pour obtenir rapidement quelques matrices particulières.
print( np.zeros( shape=(3,5) )) # matrice de 0s
print( np.eye(4))# matrice identité de taille 4, identity(4) convient aussi
print( np.diag(v)) # matrice diagonale
print( np.ones( (2,3) ))# matrice de 1s
Les opérations vues précédemment sur les quantités de type array s'appliquent de manière similaire sur les matrices.
print("m :")
print(m)
print()
print("10 * m :")
print(10 * m)
print()
print("élévation des coefficients de m au carré :")
print(m ** 2)
print()
print("m + matrice de 1s :")
print( m + np.ones( (2,3) ))
On dispose en plus de quelques opérations propres aux matrices.
print( m.transpose()) # transposée
print()
print(m.T) # autre façon d'obtenir la transposée
n = np.array( [ [1+1j, 1], [1-1j, 2+3*1j] ] )
print("n :")
print(n)
print()
print("matrice conjuguée :")
print(n.conj())
print()
print("matrice adjointe :")
print(n.conj().T)
Attention à l'opérateur * qui effectue un produit coefficient par coefficient.
m * m # produit coefficient par coefficient
Pour faire un produit matrice × vecteur ou matrice × matrice, il faut utiliser la fonction dot().
print(m)
print()
print(np.dot(m, np.array([0., 1., 2.]) ))
print()
print(np.dot(np.array([1., 1.]), m))
print()
print(np.dot(m, np.diag([10, 100, 1000]) ))
Affichage des lignes et des colonnes
m = np.array( [[1, 2, 3],
[4, 5, 6],
[7, 8, 9]])
# les lignes
print(m[0,:],m[1,:],m[2,:])
print("________________\n")
# les colonnes
print(m[:,0],m[:,1],m[:,2])
print(m[:,::-1]) # inversion de l'ordre des colonnes
Affectation
print(m.shape)
print(m.shape[0], m.shape[1])
for i in range(m.shape[0]):
for j in range(m.shape[1]):
m[i,j] = i + j
print(m)
f = lambda x: x**2
print(f(m))
m[:,:] = 0
print(m)
m[:] = np.array([1, 2, 3])
print(m)
m[:,2] = np.ones(3)
print(m)
m[1,:] = np.zeros(3)
print(m)