640 votes

Comment peut-on calculer la distance euclidienne avec NumPy ?

J'ai deux points dans l'espace 3D:

a = (ax, ay, az)
b = (bx, by, bz)

Je veux calculer la distance entre eux:

dist = sqrt((ax-bx)^2 + (ay-by)^2 + (az-bz)^2)

Comment puis-je faire cela avec NumPy? J'ai:

import numpy
a = numpy.array((ax, ay, az))
b = numpy.array((bx, by, bz))

0 votes

Pour être clair, vos coordonnées 3D des points sont en fait des tableaux 1D ;-)

1098voto

u0b34a0f6ae Points 14874

Utilisez numpy.linalg.norm:

dist = numpy.linalg.norm(a-b)

Cela fonctionne parce que la distance euclidienne est la norme l2, et que la valeur par défaut du paramètre ord dans numpy.linalg.norm est 2. Pour plus de théorie, consultez Introduction to Data Mining:

enter image description here

14 votes

Les docs linalg.norm peuvent être trouvés ici : docs.scipy.org/doc/numpy/reference/generated/… Mon seul vrai commentaire était de souligner la connexion entre une norme (dans ce cas, la norme de Frobenius/2-norme qui est la valeur par défaut pour la fonction de norme) et une métrique (dans ce cas, la distance euclidienne).

7 votes

Si OP souhaite calculer la distance entre un tableau de coordonnées, il est également possible d'utiliser scipy.spatial.distance.cdist.

2 votes

Ma question est: pourquoi utiliser ceci au lieu de cela? stackoverflow.com/a/21986532/189411 de scipy.spatial import distance a = (1,2,3) b = (4,5,6) dst = distance.euclidean(a,b)

207voto

Avision Points 92

Utilisez scipy.spatial.distance.euclidean:

from scipy.spatial import distance
a = (1, 2, 3)
b = (4, 5, 6)
dst = distance.euclidean(a, b)

66 votes

Si vous recherchez l'efficacité, il est préférable d'utiliser la fonction numpy. La distance scipy est deux fois plus lente que numpy.linalg.norm(a-b) (et numpy.sqrt(numpy.sum((a-b)**2))). Sur ma machine, j'obtiens 19,7 µs avec scipy (v0.15.1) et 8,9 µs avec numpy (v1.9.2). Pas une différence pertinente dans de nombreux cas, mais si elle est utilisée dans une boucle, elle peut devenir plus significative. D'après un rapide examen du code scipy, il semble être plus lent parce qu'il valide le tableau avant de calculer la distance.

0 votes

@MikePalmice oui, les fonctions scipy sont entièrement compatibles avec numpy. Mais jetez un coup d'œil à ce que aigold a suggéré ici (qui fonctionne également sur un tableau numpy, bien sûr)

0 votes

@Avision pas sûr que cela fonctionnera pour moi car mes matrices ont un nombre de lignes différent; essayer de les soustraire pour obtenir une seule matrice ne fonctionne pas

37voto

Nathan Fellman Points 31310

Une autre instance de cette méthode de résolution de problèmes:

def dist(x,y):   
    return numpy.sqrt(numpy.sum((x-y)**2))

a = numpy.array((xa,ya,za))
b = numpy.array((xb,yb,zb))
dist_a_b = dist(a,b)

1 votes

Pouvez-vous utiliser les implémentations sqrt et/ou sum de numpy? Cela devrait le rendre plus rapide (?).

1 votes

J'ai trouvé ceci de l'autre côté des interwebs norm = lambda x: N.sqrt(N.square(x).sum()) ; norm(x-y)

2 votes

Effacez cela. Il devait être quelque part. Le voici: numpy.linalg.norm(x-y)

14voto

The Demz Points 1010

Cela peut être fait comme suit. Je ne sais pas à quelle vitesse cela se fait, mais cela n'utilise pas NumPy.

from math import sqrt
a = (1, 2, 3) # Point de données 1
b = (4, 5, 6) # Point de données 2
print sqrt(sum( (a - b)**2 for a, b in zip(a, b)))

0 votes

Faire des mathématiques directement en python n'est pas une bonne idée car python est très lent, en particulier pour a, b in zip(a, b). Mais néanmoins utile.

1 votes

Tu n'as même pas besoin de compresser les a et b. sqrt(sum( (a - b)**2)) ferait l'affaire. Belle réponse d'ailleurs

10voto

Alan Points 39

Je trouve une fonction 'dist' dans matplotlib.mlab, mais je ne pense pas qu'elle soit assez pratique.

Je la poste ici juste pour référence.

import numpy as np
import matplotlib as plt

a = np.array([1, 2, 3])
b = np.array([2, 3, 4])

# Distance entre a et b
dis = plt.mlab.dist(a, b)

0 votes

Cette fonction n'est plus applicable. (mpl 3.0)

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X