Wie kann der euklidische Abstand mit NumPy berechnet werden?

529

Ich habe zwei Punkte in 3D:

(xa, ya, za)
(xb, yb, zb)

Und ich möchte die Entfernung berechnen:

dist = sqrt((xa-xb)^2 + (ya-yb)^2 + (za-zb)^2)

Was ist der beste Weg, dies mit NumPy oder mit Python im Allgemeinen zu tun? Ich habe:

import numpy
a = numpy.array((xa ,ya, za))
b = numpy.array((xb, yb, zb))
Nathan Fellman
quelle

Antworten:

885

Verwendung numpy.linalg.norm:

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

Die Theorie dahinter finden Sie in Einführung in Data Mining

Das funktioniert , weil die euklidische Abstand ist l2 - Norm und der Standardwert ord ist Parameter in numpy.linalg.norm 2.

Geben Sie hier die Bildbeschreibung ein

u0b34a0f6ae
quelle
13
Die linalg.norm-Dokumente finden Sie hier: docs.scipy.org/doc/numpy/reference/generated/… Mein einziger wirklicher Kommentar war, auf den Zusammenhang zwischen einer Norm (in diesem Fall der Frobenius-Norm / 2-Norm) hinzuweisen Dies ist die Standardeinstellung für die Normfunktion) und eine Metrik (in diesem Fall die euklidische Entfernung).
Mark Lavin
7
Wenn OP den Abstand zwischen einem Koordinatenarray berechnen wollte, kann auch scipy.spatial.distance.cdist verwendet werden .
Mnky9800n
2
meine frage ist: warum dies im gegensatz dazu verwenden? stackoverflow.com/a/21986532/189411 from scipy.spatial import distance a = (1,2,3) b = (4,5,6) dst = distance.euclidean (a, b)
Domenico Monaco
2
aktualisierter Link zu SciPys CDIST-Funktion: docs.scipy.org/doc/scipy/reference/generated/…
Steven C. Howell
Es gibt noch schnellere Methoden als numpy.linalg.norm: semantive.com/blog/…
Muhammad Ashfaq
161

Dafür gibt es in SciPy eine Funktion. Es heißt Euklidisch .

Beispiel:

from scipy.spatial import distance
a = (1, 2, 3)
b = (4, 5, 6)
dst = distance.euclidean(a, b)
Eine Vision
quelle
56
Wenn Sie nach Effizienz suchen, ist es besser, die Numpy-Funktion zu verwenden. Der Scipy-Abstand ist doppelt so langsam wie numpy.linalg.norm (ab) (und numpy.sqrt (numpy.sum ((ab) ** 2))). Auf meiner Maschine bekomme ich 19,7 µs mit scipy (v0.15.1) und 8,9 µs mit numpy (v1.9.2). In vielen Fällen kein relevanter Unterschied, aber wenn er sich in einer Schleife befindet, kann er an Bedeutung gewinnen. Ein kurzer Blick auf den Scipy-Code scheint langsamer zu sein, da er das Array vor der Berechnung der Entfernung überprüft.
Algold
@ MikePalmice Ja, Scipy-Funktionen sind voll kompatibel mit Numpy. Aber schauen Sie sich an, was Aigold hier vorgeschlagen hat (was natürlich auch auf Numpy Array funktioniert)
Avision
@Avision ist sich nicht sicher, ob es für mich funktioniert, da meine Matrizen eine unterschiedliche Anzahl von Zeilen haben. Der Versuch, sie zu subtrahieren, um eine Matrix zu erhalten, funktioniert nicht
Björks größter Fan
@ MikePalmice was genau versuchst du mit diesen beiden Matrizen zu berechnen? Was ist die erwartete Eingabe / Ausgabe?
Avision
ty für die Nachverfolgung. Hier finden Sie eine Beschreibung: stats.stackexchange.com/questions/322620/… . Ich habe 2 Tabellen mit 'Operationen'; Jedes hat ein Code-Label, aber die beiden Labelsätze sind völlig unterschiedlich. Mein Ziel ist es, den besten oder nächstgelegenen Code aus der zweiten Tabelle zu finden, der einem festen Code in der ersten entspricht (ich weiß, wie die Antwort aus der manuellen Überprüfung lauten sollte, möchte aber später auf Hunderte von Tabellen skalieren). Die erste Teilmenge ist also festgelegt. Ich berechne den Durchschnitt euklid dist bw dies und alle Code-Teilmengen der 2., dann sortiere
Björks Nummer eins Fan
108

Für alle, die mehrere Entfernungen gleichzeitig berechnen möchten , habe ich einen kleinen Vergleich mit perfplot (einem kleinen Projekt von mir) durchgeführt.

Der erste Rat ist, Ihre Daten so zu organisieren, dass die Arrays eine Dimension haben (3, n)(und offensichtlich C-zusammenhängend sind). Wenn das Hinzufügen in der zusammenhängenden ersten Dimension erfolgt, sind die Dinge schneller und es spielt keine Rolle, ob Sie sqrt-summit axis=0, linalg.normmit axis=0oder verwenden

a_min_b = a - b
numpy.sqrt(numpy.einsum('ij,ij->j', a_min_b, a_min_b))

Das ist mit leichtem Abstand die schnellste Variante. (Das gilt eigentlich auch nur für eine Zeile.)

Die Varianten, bei denen Sie über die zweite Achse summieren axis=1, sind alle wesentlich langsamer.

Geben Sie hier die Bildbeschreibung ein


Code zur Reproduktion der Handlung:

import numpy
import perfplot
from scipy.spatial import distance


def linalg_norm(data):
    a, b = data[0]
    return numpy.linalg.norm(a - b, axis=1)


def linalg_norm_T(data):
    a, b = data[1]
    return numpy.linalg.norm(a - b, axis=0)


def sqrt_sum(data):
    a, b = data[0]
    return numpy.sqrt(numpy.sum((a - b) ** 2, axis=1))


def sqrt_sum_T(data):
    a, b = data[1]
    return numpy.sqrt(numpy.sum((a - b) ** 2, axis=0))


def scipy_distance(data):
    a, b = data[0]
    return list(map(distance.euclidean, a, b))


def sqrt_einsum(data):
    a, b = data[0]
    a_min_b = a - b
    return numpy.sqrt(numpy.einsum("ij,ij->i", a_min_b, a_min_b))


def sqrt_einsum_T(data):
    a, b = data[1]
    a_min_b = a - b
    return numpy.sqrt(numpy.einsum("ij,ij->j", a_min_b, a_min_b))


def setup(n):
    a = numpy.random.rand(n, 3)
    b = numpy.random.rand(n, 3)
    out0 = numpy.array([a, b])
    out1 = numpy.array([a.T, b.T])
    return out0, out1


perfplot.save(
    "norm.png",
    setup=setup,
    n_range=[2 ** k for k in range(22)],
    kernels=[
        linalg_norm,
        linalg_norm_T,
        scipy_distance,
        sqrt_sum,
        sqrt_sum_T,
        sqrt_einsum,
        sqrt_einsum_T,
    ],
    logx=True,
    logy=True,
    xlabel="len(x), len(y)",
)
Nico Schlömer
quelle
3
Vielen Dank. Ich habe heute etwas Neues gelernt! Für ein eindimensionales Array i,i->
lautet
4
Es wäre immer cooler, wenn es einen Vergleich des Speicherverbrauchs
gäbe
Ich möchte Ihren Code verwenden, habe aber Probleme zu verstehen, wie die Daten organisiert werden sollen. Kannst du ein Beispiel geben? Wie muss datadas aussehen?
Johannes Wiesner
1
Wirklich ordentliches Projekt und Ergebnisse. Ich habe einige halbe Pläne der gleichen Art gemacht, also denke ich, ich werde zu Ihrem Projekt wechseln und die Unterschiede beitragen, wenn Sie sie mögen.
Mad Physicist
42

Ich möchte die einfache Antwort mit verschiedenen Leistungsnotizen erläutern. np.linalg.norm kann vielleicht mehr als Sie brauchen:

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

Erstens: Diese Funktion dient zum Überarbeiten einer Liste und zum Zurückgeben aller Werte, z. B. zum Vergleichen der Entfernung von pAder Punktmenge sP:

sP = set(points)
pA = point
distances = np.linalg.norm(sP - pA, ord=2, axis=1.)  # 'distances' is a list

Denken Sie an verschiedene Dinge:

  • Python-Funktionsaufrufe sind teuer.
  • [Normal] Python speichert keine Namenssuche zwischen.

Damit

def distance(pointA, pointB):
    dist = np.linalg.norm(pointA - pointB)
    return dist

ist nicht so unschuldig wie es aussieht.

>>> dis.dis(distance)
  2           0 LOAD_GLOBAL              0 (np)
              2 LOAD_ATTR                1 (linalg)
              4 LOAD_ATTR                2 (norm)
              6 LOAD_FAST                0 (pointA)
              8 LOAD_FAST                1 (pointB)
             10 BINARY_SUBTRACT
             12 CALL_FUNCTION            1
             14 STORE_FAST               2 (dist)

  3          16 LOAD_FAST                2 (dist)
             18 RETURN_VALUE

Erstens - jedes Mal, wenn wir es aufrufen, müssen wir eine globale Suche nach "np", eine Suche nach "linalg" und eine Suche nach "norm" durchführen, und der Aufwand für das bloße Aufrufen der Funktion kann Dutzenden von Python entsprechen Anleitung.

Zuletzt haben wir zwei Vorgänge verschwendet, um das Ergebnis zu speichern und für die Rückgabe neu zu laden ...

Erster Durchgang bei der Verbesserung: Beschleunigen Sie die Suche, überspringen Sie den Speicher

def distance(pointA, pointB, _norm=np.linalg.norm):
    return _norm(pointA - pointB)

Wir werden umso schlanker:

>>> dis.dis(distance)
  2           0 LOAD_FAST                2 (_norm)
              2 LOAD_FAST                0 (pointA)
              4 LOAD_FAST                1 (pointB)
              6 BINARY_SUBTRACT
              8 CALL_FUNCTION            1
             10 RETURN_VALUE

Der Aufwand für Funktionsaufrufe beträgt jedoch noch einige Arbeit. Und Sie sollten Benchmarks durchführen, um festzustellen, ob Sie die Mathematik besser selbst durchführen können:

def distance(pointA, pointB):
    return (
        ((pointA.x - pointB.x) ** 2) +
        ((pointA.y - pointB.y) ** 2) +
        ((pointA.z - pointB.z) ** 2)
    ) ** 0.5  # fast sqrt

Auf einigen Plattformen **0.5ist schneller als math.sqrt. Ihr Kilometerstand kann variieren.

**** Erweiterte Leistungshinweise.

Warum berechnen Sie die Entfernung? Wenn der einzige Zweck darin besteht, es anzuzeigen,

 print("The target is %.2fm away" % (distance(a, b)))

weiter machen. Wenn Sie jedoch Entfernungen vergleichen, Entfernungsprüfungen durchführen usw., möchte ich einige nützliche Leistungsbeobachtungen hinzufügen.

Nehmen wir zwei Fälle: Sortieren nach Entfernung oder Auslesen einer Liste nach Elementen, die eine Bereichsbeschränkung erfüllen.

# Ultra naive implementations. Hold onto your hat.

def sort_things_by_distance(origin, things):
    return things.sort(key=lambda thing: distance(origin, thing))

def in_range(origin, range, things):
    things_in_range = []
    for thing in things:
        if distance(origin, thing) <= range:
            things_in_range.append(thing)

Das erste, woran wir uns erinnern müssen, ist, dass wir Pythagoras verwenden , um die Entfernung ( dist = sqrt(x^2 + y^2 + z^2)) zu berechnen, damit wir viele sqrtAnrufe tätigen. Mathe 101:

dist = root ( x^2 + y^2 + z^2 )
:.
dist^2 = x^2 + y^2 + z^2
and
sq(N) < sq(M) iff M > N
and
sq(N) > sq(M) iff N > M
and
sq(N) = sq(M) iff N == M

Kurz gesagt: Bis wir tatsächlich den Abstand in einer Einheit von X anstelle von X ^ 2 benötigen, können wir den schwierigsten Teil der Berechnungen eliminieren.

# Still naive, but much faster.

def distance_sq(left, right):
    """ Returns the square of the distance between left and right. """
    return (
        ((left.x - right.x) ** 2) +
        ((left.y - right.y) ** 2) +
        ((left.z - right.z) ** 2)
    )

def sort_things_by_distance(origin, things):
    return things.sort(key=lambda thing: distance_sq(origin, thing))

def in_range(origin, range, things):
    things_in_range = []

    # Remember that sqrt(N)**2 == N, so if we square
    # range, we don't need to root the distances.
    range_sq = range**2

    for thing in things:
        if distance_sq(origin, thing) <= range_sq:
            things_in_range.append(thing)

Großartig, beide Funktionen machen keine teuren Quadratwurzeln mehr. Das geht viel schneller. Wir können in_range auch verbessern, indem wir es in einen Generator konvertieren:

def in_range(origin, range, things):
    range_sq = range**2
    yield from (thing for thing in things
                if distance_sq(origin, thing) <= range_sq)

Dies hat insbesondere Vorteile, wenn Sie Folgendes tun:

if any(in_range(origin, max_dist, things)):
    ...

Aber wenn das nächste, was Sie tun werden, eine Distanz erfordert,

for nearby in in_range(origin, walking_distance, hotdog_stands):
    print("%s %.2fm" % (nearby.name, distance(origin, nearby)))

erwägen, Tupel zu ergeben:

def in_range_with_dist_sq(origin, range, things):
    range_sq = range**2
    for thing in things:
        dist_sq = distance_sq(origin, thing)
        if dist_sq <= range_sq: yield (thing, dist_sq)

Dies kann besonders nützlich sein, wenn Sie Entfernungsprüfungen verketten können ('Dinge finden, die sich in der Nähe von X und innerhalb von Nm von Y befinden', da Sie die Entfernung nicht erneut berechnen müssen).

Aber was ist, wenn wir eine wirklich große Liste von suchen thingsund davon ausgehen, dass viele von ihnen nicht in Betracht gezogen werden sollten?

Es gibt tatsächlich eine sehr einfache Optimierung:

def in_range_all_the_things(origin, range, things):
    range_sq = range**2
    for thing in things:
        dist_sq = (origin.x - thing.x) ** 2
        if dist_sq <= range_sq:
            dist_sq += (origin.y - thing.y) ** 2
            if dist_sq <= range_sq:
                dist_sq += (origin.z - thing.z) ** 2
                if dist_sq <= range_sq:
                    yield thing

Ob dies nützlich ist, hängt von der Größe der 'Dinge' ab.

def in_range_all_the_things(origin, range, things):
    range_sq = range**2
    if len(things) >= 4096:
        for thing in things:
            dist_sq = (origin.x - thing.x) ** 2
            if dist_sq <= range_sq:
                dist_sq += (origin.y - thing.y) ** 2
                if dist_sq <= range_sq:
                    dist_sq += (origin.z - thing.z) ** 2
                    if dist_sq <= range_sq:
                        yield thing
    elif len(things) > 32:
        for things in things:
            dist_sq = (origin.x - thing.x) ** 2
            if dist_sq <= range_sq:
                dist_sq += (origin.y - thing.y) ** 2 + (origin.z - thing.z) ** 2
                if dist_sq <= range_sq:
                    yield thing
    else:
        ... just calculate distance and range-check it ...

Und noch einmal, erwägen Sie, dist_sq zu erhalten. Unser Hotdog-Beispiel lautet dann:

# Chaining generators
info = in_range_with_dist_sq(origin, walking_distance, hotdog_stands)
info = (stand, dist_sq**0.5 for stand, dist_sq in info)
for stand, dist in info:
    print("%s %.2fm" % (stand, dist))
kfsone
quelle
1
Warum nicht eine solche optimierte Funktion zu numpy hinzufügen? Eine Erweiterung für Pandas wäre auch großartig für eine Frage wie diese stackoverflow.com/questions/47643952/…
Keith
3
Ich habe Ihren ersten mathematischen Ansatz zur Entfernung bearbeitet. Sie haben eine verwendet pointZ, die es nicht gab. Ich denke, Sie meinten zwei Punkte im dreidimensionalen Raum und ich habe sie entsprechend bearbeitet. Wenn ich mich geirrt habe, lass es mich wissen.
Bram Vanroy
37

Ein weiteres Beispiel für diese Problemlösungsmethode :

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)
Nathan Fellman
quelle
1
Können Sie die sqrt- und / oder sum-Implementierungen von numpy verwenden? Das sollte es schneller machen (?).
u0b34a0f6ae
1
Ich fand das auf der anderen Seite der Interwebs norm = lambda x: N.sqrt(N.square(x).sum()); norm(x-y)
u0b34a0f6ae
2
Vergiss das. es musste irgendwo sein. hier ist es:numpy.linalg.norm(x-y)
u0b34a0f6ae
13

Ab Python 3.8dem Start stellt das mathModul direkt die distFunktion bereit , die den euklidischen Abstand zwischen zwei Punkten zurückgibt (angegeben als Tupel oder Koordinatenlisten):

from math import dist

dist((1, 2, 6), (-2, 3, 2)) # 5.0990195135927845

Und wenn Sie mit Listen arbeiten:

dist([1, 2, 6], [-2, 3, 2]) # 5.0990195135927845
Xavier Guihot
quelle
12

Dies kann wie folgt erfolgen. Ich weiß nicht, wie schnell es ist, aber es verwendet NumPy nicht.

from math import sqrt
a = (1, 2, 3) # Data point 1
b = (4, 5, 6) # Data point 2
print sqrt(sum( (a - b)**2 for a, b in zip(a, b)))
Der Demz
quelle
Mathe direkt in Python zu machen ist keine gute Idee, da Python besonders langsam ist for a, b in zip(a, b). Aber trotzdem nützlich.
Sigex
10

Ich finde eine 'dist'-Funktion in matplotlib.mlab, aber ich denke nicht, dass es praktisch genug ist.

Ich poste es hier nur als Referenz.

import numpy as np
import matplotlib as plt

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

# Distance between a and b
dis = plt.mlab.dist(a, b)
Alan Wang
quelle
Dies gilt nicht mehr. (mpl 3.0)
Nico Schlömer
8

Ich mag np.dot(Punktprodukt):

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

distance = (np.dot(a-b,a-b))**.5
Reiseknochen
quelle
8

Ein schöner Einzeiler:

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

Wenn es jedoch um Geschwindigkeit geht, würde ich empfehlen, an Ihrem Computer zu experimentieren. Ich habe festgestellt, dass die Verwendung von mathBibliotheken sqrtmit dem** Operator für das Quadrat auf meinem Computer viel schneller ist als die einzeilige NumPy-Lösung.

Ich habe meine Tests mit diesem einfachen Programm durchgeführt:

#!/usr/bin/python
import math
import numpy
from random import uniform

def fastest_calc_dist(p1,p2):
    return math.sqrt((p2[0] - p1[0]) ** 2 +
                     (p2[1] - p1[1]) ** 2 +
                     (p2[2] - p1[2]) ** 2)

def math_calc_dist(p1,p2):
    return math.sqrt(math.pow((p2[0] - p1[0]), 2) +
                     math.pow((p2[1] - p1[1]), 2) +
                     math.pow((p2[2] - p1[2]), 2))

def numpy_calc_dist(p1,p2):
    return numpy.linalg.norm(numpy.array(p1)-numpy.array(p2))

TOTAL_LOCATIONS = 1000

p1 = dict()
p2 = dict()
for i in range(0, TOTAL_LOCATIONS):
    p1[i] = (uniform(0,1000),uniform(0,1000),uniform(0,1000))
    p2[i] = (uniform(0,1000),uniform(0,1000),uniform(0,1000))

total_dist = 0
for i in range(0, TOTAL_LOCATIONS):
    for j in range(0, TOTAL_LOCATIONS):
        dist = fastest_calc_dist(p1[i], p2[j]) #change this line for testing
        total_dist += dist

print total_dist

Läuft auf meiner Maschine math_calc_distviel schneller alsnumpy_calc_dist : 1,5 Sekunden gegenüber 23,5 Sekunden.

Um einen messbaren Unterschied zwischen fastest_calc_distund zu erhalten, musste math_calc_distich bis TOTAL_LOCATIONSzu 6000. Dann fastest_calc_distdauert es ~ 50 Sekunden, während es math_calc_dist~ 60 Sekunden dauert.

Sie können auch experimentieren numpy.sqrtund numpy.squareobwohl beide langsamer waren als die mathAlternativen auf meinem Computer.

Meine Tests wurden mit Python 2.6.6 ausgeführt.

user118662
quelle
48
Sie verstehen schlecht, wie man Numpy verwendet ... Verwenden Sie keine Schleifen oder Listenverständnisse. Wenn Sie durchlaufen und die Funktion auf jedes Element anwenden , sind die Numpy-Funktionen langsamer. Der springende Punkt ist, Dinge zu vektorisieren.
Joe Kington
Wenn ich den Aufruf numpy.array in die Schleife verschiebe, in der ich die Punkte erstelle, erhalte ich mit numpy_calc_dist bessere Ergebnisse, aber es ist immer noch 10x langsamer als am schnellsten_calc_dist. Wenn ich so viele Punkte habe und den Abstand zwischen den einzelnen Paaren ermitteln muss, bin ich mir nicht sicher, was ich sonst noch tun kann, um die Anzahl zu verbessern.
user118662
15
Mir ist klar, dass dieser Thread alt ist, aber ich möchte nur verstärken, was Joe gesagt hat. Sie verwenden numpy nicht richtig. Was Sie berechnen, ist die Summe der Entfernung von jedem Punkt in p1 zu jedem Punkt in p2. Die Lösung mit numpy / scipy ist auf meinem Computer über 70-mal schneller. Machen Sie p1 und p2 zu einem Array (auch mit einer Schleife, wenn Sie sie als Dikte definiert haben). Dann können Sie die Gesamtsumme in einem Schritt erhalten scipy.spatial.distance.cdist(p1, p2).sum(). Das ist es.
Scott B
3
Oder verwenden Sie numpy.linalg.norm(p1-p2).sum(), um die Summe zwischen jedem Punkt in p1 und dem entsprechenden Punkt in p2 zu erhalten (dh nicht jedem Punkt in p1 zu jedem Punkt in p2). Und wenn Sie jeden Punkt in p1 bis zu jedem Punkt in p2 wollen und nicht wie in meinem vorherigen Kommentar scipy verwenden möchten, können Sie np.apply_along_axis zusammen mit numpy.linalg.norm verwenden, um es noch viel, viel schneller zu machen dann Ihre "schnellste" Lösung.
Scott B
2
Frühere Versionen von NumPy hatten sehr langsame Normimplementierungen. In aktuellen Versionen ist dies alles nicht erforderlich.
Fred Foo
8

Sie können einfach die Vektoren subtrahieren und dann innerproduzieren.

Folgen Sie Ihrem Beispiel,

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

tmp = a - b
sum_squared = numpy.dot(tmp.T, tmp)
result = sqrt(sum_squared)
PuercoPop
quelle
5
Dies gibt mir das Quadrat der Entfernung. Sie vermissen hier ein Quadrat.
Nathan Fellman
6

Mit aund bwie Sie sie definiert haben, können Sie auch verwenden:

distance = np.sqrt(np.sum((a-b)**2))
Alejandro Sazo
quelle
6

Mit Python 3.8 ist das sehr einfach.

https://docs.python.org/3/library/math.html#math.dist

math.dist(p, q)

Geben Sie den euklidischen Abstand zwischen zwei Punkten p und q zurück, die jeweils als Folge (oder iterierbar) von Koordinaten angegeben sind. Die beiden Punkte müssen dieselbe Abmessung haben.

Ungefähr gleichbedeutend mit:

sqrt(sum((px - qx) ** 2.0 for px, qx in zip(p, q)))

Hakiko
quelle
5

Hier ist ein prägnanter Code für die euklidische Entfernung in Python, wenn zwei Punkte in Python als Listen dargestellt werden.

def distance(v1,v2): 
    return sum([(x-y)**2 for (x,y) in zip(v1,v2)])**(0.5)
Andy Lee
quelle
1
Numpy akzeptiert auch Listen als Eingaben (keine explizite Übergabe eines Numpy-Arrays erforderlich)
Alejandro Sazo
4

Seit Python 3.8

Seit Python 3.8 enthält das mathModul die Funktion math.dist().
Siehe hier https://docs.python.org/3.8/library/math.html#math.dist .

math.dist (p1, p2) Gibt
den euklidischen Abstand zwischen zwei Punkten p1 und p2 zurück, die jeweils als Folge (oder iterierbar) von Koordinaten angegeben sind.

import math
print( math.dist( (0,0),   (1,1)   )) # sqrt(2) -> 1.4142
print( math.dist( (0,0,0), (1,1,1) )) # sqrt(3) -> 1.7321
ePi272314
quelle
3

Berechnen Sie den euklidischen Abstand für den mehrdimensionalen Raum:

 import math

 x = [1, 2, 6] 
 y = [-2, 3, 2]

 dist = math.sqrt(sum([(xi-yi)**2 for xi,yi in zip(x, y)]))
 5.0990195135927845
Gennady Nikitin
quelle
2
import numpy as np
from scipy.spatial import distance
input_arr = np.array([[0,3,0],[2,0,0],[0,1,3],[0,1,2],[-1,0,1],[1,1,1]]) 
test_case = np.array([0,0,0])
dst=[]
for i in range(0,6):
    temp = distance.euclidean(test_case,input_arr[i])
    dst.append(temp)
print(dst)
Ankur Nadda
quelle
2
Was ist der Unterschied zu dieser Antwort ?
xskxzr
2
import math

dist = math.hypot(math.hypot(xa-xb, ya-yb), za-zb)
Jonas De Schouwer
quelle
2

Sie können die Formel leicht verwenden

distance = np.sqrt(np.sum(np.square(a-b)))

Dies bedeutet eigentlich nichts anderes als die Verwendung des Satzes von Pythagoras zur Berechnung der Entfernung, indem die Quadrate von Δx, Δy und Δz addiert und das Ergebnis verwurzelt werden.

Jonas De Schouwer
quelle
1

Finden Sie zuerst die Differenz zweier Matrizen. Wenden Sie dann die elementweise Multiplikation mit dem Multiplikationsbefehl von numpy an. Finden Sie danach die Summation der elementweise multiplizierten neuen Matrix. Finden Sie schließlich die Quadratwurzel der Summation.

def findEuclideanDistance(a, b):
    euclidean_distance = a - b
    euclidean_distance = np.sum(np.multiply(euclidean_distance, euclidean_distance))
    euclidean_distance = np.sqrt(euclidean_distance)
    return euclidean_distance
Johncasey
quelle
1
import numpy as np
# any two python array as two points
a = [0, 0]
b = [3, 4]

Sie ändern zuerst die Liste in ein numpy-Array und gehen folgendermaßen vor : print(np.linalg.norm(np.array(a) - np.array(b))). Zweite Methode direkt aus der Python-Liste als:print(np.linalg.norm(np.subtract(a,b)))

Uddhav Gautam
quelle