HOWTO · NumPy
Calculer la distance euclidienne en Python
Ce tutoriel montre comment calculer la distance euclidienne en python
Sur cette page
Pour deux tableaux NumPy représentant des points ayant le même nombre de coordonnées, calculez la distance euclidienne avec np.linalg.norm(point_a - point_b). La soustraction crée les écarts entre coordonnées et la norme L2 du vecteur les réduit à une distance unique non négative.
Comprendre la formule de la distance euclidienne
Pour les points (a=(a_1,\ldots,a_n)) et (b=(b_1,\ldots,b_n)), la distance euclidienne est la racine carrée de la somme des carrés des écarts de coordonnées :
Dans NumPy, np.linalg.norm(a - b) exprime directement cette définition. Avec un tableau d’écarts unidimensionnel et sans argument ord, np.linalg.norm calcule sa norme 2. Les deux entrées doivent décrire des points de dimensions compatibles pour que la soustraction ait le sens attendu.
Préparer les coordonnées d’entrée
Les positions des coordonnées doivent décrire les mêmes axes dans le même ordre : comparez la première coordonnée d’un point avec la première de l’autre, et ainsi de suite. Représentez un point par un tableau unidimensionnel de forme (coordinates,). Deux tableaux de forme (3,), par exemple, représentent deux points dans le même espace à trois dimensions ; ils ne représentent pas trois distances indépendantes.
Vous pouvez convertir des tuples et des listes avec np.asarray(values, dtype=float) avant la soustraction. Le type flottant accepte les coordonnées entières ou décimales et évite le bouclage des entiers non signés lorsqu’une coordonnée est inférieure à celle qui lui correspond. Si les entrées sont déjà des tableaux NumPy flottants adaptés, cette conversion est inutile. Évitez d’aplatir des données multidimensionnelles arbitraires uniquement pour faire correspondre les formes : cela peut masquer une erreur de structure d’entrée plutôt que la corriger.
Les exemples ci-dessous ont été exécutés avec Python 3.14.7, NumPy 2.5.3 et SciPy 1.18.1. Les API présentées sont établies, mais une application doit employer des versions compatibles avec l’environnement Python qu’elle prend en charge. SciPy est facultatif, sauf si vous utilisez sa méthode ou ses outils de distances par paires.
Calculer la distance entre deux points
L’exemple vérifié suivant compare l’expression de norme recommandée à la formule explicite, à une formulation par produit scalaire, à math.dist de la bibliothèque standard et à scipy.spatial.distance.euclidean de SciPy. Les cinq calculs donnent le même résultat pour cette paire de points.
"""Verify equivalent Euclidean-distance APIs for one pair of points."""
import math
import numpy as np
from scipy.spatial import distance
point_a = np.array([1.0, 2.0, 3.0])
point_b = np.array([4.0, 5.0, 6.0])
print(f"np.linalg.norm: {np.linalg.norm(point_a - point_b)}")
print(f"formula: {np.sqrt(np.sum((point_a - point_b) ** 2))}")
delta = point_a - point_b
print(f"dot product: {np.sqrt(np.dot(delta, delta))}")
print(f"math.dist: {math.dist(point_a, point_b)}")
print(f"distance.euclidean: {distance.euclidean(point_a, point_b)}")
np.linalg.norm: 5.196152422706632
formula: 5.196152422706632
dot product: 5.196152422706632
math.dist: 5.196152422706632
distance.euclidean: 5.196152422706632
La formule explicite utilise conceptuellement la mise au carré élément par élément avec NumPy, suivie d’une somme et d’une racine carrée. La forme avec exponentiation de l’exemple garde le calcul complet dans une seule expression. La variante par produit scalaire calcule la même somme des carrés, car np.dot(delta, delta) multiplie les écarts correspondants puis les additionne.
Utilisez np.linalg.norm lorsque les points sont déjà des tableaux ou participent à un calcul NumPy plus vaste. Cette forme exprime clairement l’opération vectorielle sans détailler la réduction.
Calculer des distances par ligne avec axis=1
Pour plusieurs points stockés comme lignes d’un tableau bidimensionnel, soustrayez un point de référence et définissez axis=1. NumPy diffuse le tableau de référence sur les lignes, tandis que axis=1 demande à np.linalg.norm de renvoyer une norme par ligne au lieu d’une norme pour toute la matrice.
"""Verify row-wise distances from several points to one reference point."""
import numpy as np
points = np.array([[1.0, 2.0, 3.0], [4.0, 5.0, 6.0]])
reference = np.array([1.0, 2.0, 3.0])
print(np.linalg.norm(points - reference, axis=1))
[0. 5.19615242]
La première ligne est identique à la référence, sa distance est donc nulle. Le second résultat est la distance calculée dans l’exemple à une paire. Ce schéma couvre les distances d’un point à plusieurs ; pour toutes les distances par paires entre deux collections, utilisez une routine dédiée telle que scipy.spatial.distance.cdist au lieu de créer un grand tableau intermédiaire diffusé sans considérer l’utilisation de mémoire.
Choisir entre NumPy, math.dist et SciPy
La meilleure méthode dépend du code environnant, et non d’une affirmation universelle de rapidité :
- Utilisez
np.linalg.norm(a - b)pour les tableaux NumPy, les flux vectorisés et les calculs par ligne avecaxis. - Utilisez
math.dist(a, b)pour une paire d’itérables de coordonnées Python ordinaires lorsque NumPy n’est pas nécessaire ailleurs. - Utilisez
scipy.spatial.distance.euclidean(a, b)lorsque SciPy est déjà une dépendance ou que le calcul appartient à son ensemble plus large d’outils de distance. - Utilisez la formule explicite de somme des carrés ou le produit scalaire pour enseigner, auditer ou adapter le calcul sous-jacent. Ils ne rendent pas le résultat plus euclidien que l’expression de norme.
Convertir des listes avec np.asarray(..., dtype=float) est utile avant une soustraction NumPy, car les listes Python ne prennent pas en charge la soustraction élément par élément. math.dist accepte directement des itérables de coordonnées de même longueur, tandis que les choix NumPy et SciPy nécessitent leurs paquets respectifs.
Gérer les formes incompatibles et les types de données numériques
Deux points individuels doivent avoir le même nombre de coordonnées. Des formes unidimensionnelles incompatibles ne peuvent pas être diffusées ensemble ; NumPy lève donc un ValueError avant de pouvoir calculer une distance.
"""Capture the diagnostic for points with incompatible dimensions."""
import numpy as np
point_a = np.array([1.0, 2.0])
point_b = np.array([3.0, 4.0, 5.0])
try:
np.linalg.norm(point_a - point_b)
except ValueError as error:
print(f"ValueError: {error}".rstrip())
ValueError: operands could not be broadcast together with shapes (2,) (3,)
Vérifiez les formes avant la soustraction lorsque les dimensions proviennent d’une saisie utilisateur ou de données externes. Pour les distances par ligne, un tableau de points de forme (rows, coordinates) est compatible avec une référence de forme (coordinates,) ; une autre forme peut se diffuser de manière involontaire ou échouer.
Convertissez aussi les coordonnées entières non signées en type signé ou flottant avant de soustraire. Une soustraction non signée peut boucler au lieu de représenter un écart de coordonnée négatif, ce qui rend la norme suivante incorrecte. Les tableaux flottants employés dans les exemples évitent ce problème et acceptent des coordonnées non entières.
Pour une paire de points NumPy de dimensions égales, np.linalg.norm(point_a - point_b) est le choix concis par défaut. Ajoutez axis=1 pour les distances par ligne et validez les formes et les types de données dès que la structure d’entrée n’est pas déjà garantie.