Comment effectuer des opérations matricielles avec NumPy

Comment effectuer des opérations matricielles avec NumPy


Numpy_cover-scaled Comment effectuer des opérations matricielles avec NumPy NEWS
photo par Vlado Paunovic

NumPy est une bibliothèque Python puissante, offrant une vaste collection de fonctions mathématiques et prenant en charge la création de matrices et de tableaux multidimensionnels sur lesquels ces fonctions peuvent être appliquées.

Dans ce tutoriel concis, vous apprendrez à effectuer plusieurs opérations matricielles de base avec NumPy.

Matrices et tableaux dans NumPy

Dans NumPy, une matrice est définie comme un tableau strictement bidimensionnel, qui conserve cette bidimensionnalité après l’application d’opérations mathématiques. Bien que cela puisse être implémenté en utilisant la classe np.matrix, NumPy ne recommande plus son utilisation car elle pourrait être supprimée à l’avenir. L’alternative recommandée est d’utiliser le type de tableau à N dimensions, ndarray.

La principale différence entre un ndarray et une matrice dans NumPy est que le premier peut avoir n’importe quelle dimensionnalité et n’est pas limité aux opérations bidimensionnelles.

Par conséquent, dans ce tutoriel, nous nous concentrerons sur l’implémentation de plusieurs opérations matricielles de base sur des tableaux à 2 dimensions, créés à l’aide de np.ndarray.

Création de tableaux NumPy

Commençons par importer le package NumPy, puis créons deux tableaux bidimensionnels composés de deux lignes et trois colonnes chacun. Ces tableaux seront utilisés dans les exemples suivants de ce tutoriel :

# Import NumPy package
import numpy as np

# Create arrays
a1 = np.array([[0, 1, 0], [2, 3, 2]])
a2 = np.array([[3, 4, 3], [5, 6, 5]])

L’attribut shape nous permet de confirmer les dimensions du tableau :

# Print one of the arrays
print('Array 1:', 'n', a1, 'n Shape: n', a1.shape)

Sortie :

Array 1: 
[[0 1 0]
[2 3 2]]

Shape: (2, 3)

Opérations de base sur les tableaux

NumPy fournit ses propres fonctions pour effectuer des additions, soustractions, divisions et multiplications de tableaux par éléments. De plus, NumPy exploite également les opérateurs arithmétiques de Python en étendant leurs fonctionnalités pour gérer les opérations de tableau par élément.

Commençons par l’addition élément par élément entre les tableaux a1 et a2 par exemple.

L’addition par élément de deux tableaux peut être réalisée en utilisant la fonction np.add ou l’opérateur surchargé + :

# Using np.add
func_add = np.add(a1, a2)

# Using the + operator
op_add = a1 + a2

En imprimant les résultats, on peut confirmer qu’ils produisent tous deux le même résultat :

# Print results
print('Function: n', func_add, 'nn', 'Operator: n', op_add)

Sortie :

Function: 
[[3 5 3]
[7 9 7]]

Operator:
[[3 5 3]
[7 9 7]]

Cependant, si on devait les chronométrer, on peut remarquer une petite différence :

import numpy as np
import timeit

def func():

a1 = np.array([[0, 1, 0], [2, 3, 2]])
a2 = np.array([[3, 4, 3], [5, 6, 5]])
np.add(a1, a2)

def op():

a1 = np.array([[0, 1, 0], [2, 3, 2]])
a2 = np.array([[3, 4, 3], [5, 6, 5]])
a1 + a2

# Timing the functions over 100000 iterations
func_time = timeit.timeit(func, number=100000)
op_time = timeit.timeit(op, number=100000)

# Print timing results
print('Function:', func_time, 'n', 'Operator:', op_time)

Sortie :

Function: 0.2588757239282131 
Operator: 0.24321464297827333

Ici, on peut voir que la fonction NumPy np.add fonctionne légèrement plus lentement que l’opérateur +. Cela est principalement dû au fait que la fonction add introduit une vérification de type pour convertir toutes les entrées array_like (telles que des listes) en tableaux avant d’effectuer l’opération d’addition. Cela introduit une surcharge de calcul supplémentaire par rapport à l’opérateur +.

Cependant, une telle mesure rend également la fonction np.add moins sujette aux erreurs. Par exemple, appliquer np.add à des entrées de type list fonctionne toujours (par exemple np.add([1, 1], [2, 2])), tandis qu’appliquer l’opérateur + entraîne une concaténation de liste.

De même, pour la soustraction élément par élément (en utilisant np.subtract ou -), la division (en utilisant np.divide ou /) et la multiplication (en utilisant np.multiply ou *), les fonctions NumPy effectuent une vérification de type, introduisant une petite surcharge de calcul.

Plusieurs autres opérations utiles incluent la transposition et la multiplication de tableaux.

La transposition matricielle entraîne une rotation orthogonale de la matrice et peut être réalisée en utilisant la fonction np.transpose (qui inclut la vérification de type) ou l’attribut .T :

# Using np.transpose
func_a1_T = np.transpose(a1)

# Using the .T attribute
att_a1_T = a1.T

La multiplication matricielle peut être effectuée en utilisant la fonction np.dot ou l’opérateur @ (ce dernier implémente la fonction np.matmul à partir de Python 3.5) :

# Using np.dot
func_dot = np.dot(func_a1_T, a2)

# Using the @ operator
op_dot = func_a1_T @ a2

Lorsque vous travaillez avec des tableaux à 2 dimensions, np.dot et np.matmul fonctionnent de manière identique et incluent tous deux une vérification de type.

Ressources additionnelles

Stefania Cristina, PhD, est maître de conférences au Département d’ingénierie des systèmes et de contrôle de l’Université de Malte. Ses intérêts de recherche portent sur les domaines de la vision par ordinateur et de l’apprentissage automatique.

Source