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))
python
numpy
euclidean-distance
Nathan Fellman
quelle
quelle
Dafür gibt es in SciPy eine Funktion. Es heißt Euklidisch .
Beispiel:
quelle
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 Siesqrt-sum
mitaxis=0
,linalg.norm
mitaxis=0
oder verwendenDas 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.Code zur Reproduktion der Handlung:
quelle
i,i->
data
das aussehen?Ich möchte die einfache Antwort mit verschiedenen Leistungsnotizen erläutern. np.linalg.norm kann vielleicht mehr als Sie brauchen:
Erstens: Diese Funktion dient zum Überarbeiten einer Liste und zum Zurückgeben aller Werte, z. B. zum Vergleichen der Entfernung von
pA
der PunktmengesP
:Denken Sie an verschiedene Dinge:
Damit
ist nicht so unschuldig wie es aussieht.
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
Wir werden umso schlanker:
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:
Auf einigen Plattformen
**0.5
ist schneller alsmath.sqrt
. Ihr Kilometerstand kann variieren.**** Erweiterte Leistungshinweise.
Warum berechnen Sie die Entfernung? Wenn der einzige Zweck darin besteht, es anzuzeigen,
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.
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 vielesqrt
Anrufe tätigen. Mathe 101: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.
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:
Dies hat insbesondere Vorteile, wenn Sie Folgendes tun:
Aber wenn das nächste, was Sie tun werden, eine Distanz erfordert,
erwägen, Tupel zu ergeben:
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
things
und davon ausgehen, dass viele von ihnen nicht in Betracht gezogen werden sollten?Es gibt tatsächlich eine sehr einfache Optimierung:
Ob dies nützlich ist, hängt von der Größe der 'Dinge' ab.
Und noch einmal, erwägen Sie, dist_sq zu erhalten. Unser Hotdog-Beispiel lautet dann:
quelle
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.Ein weiteres Beispiel für diese Problemlösungsmethode :
quelle
norm = lambda x: N.sqrt(N.square(x).sum())
;norm(x-y)
numpy.linalg.norm(x-y)
Ab
Python 3.8
dem Start stellt dasmath
Modul direkt diedist
Funktion bereit , die den euklidischen Abstand zwischen zwei Punkten zurückgibt (angegeben als Tupel oder Koordinatenlisten):Und wenn Sie mit Listen arbeiten:
quelle
Dies kann wie folgt erfolgen. Ich weiß nicht, wie schnell es ist, aber es verwendet NumPy nicht.
quelle
for a, b in zip(a, b)
. Aber trotzdem nützlich.Ich finde eine 'dist'-Funktion in matplotlib.mlab, aber ich denke nicht, dass es praktisch genug ist.
Ich poste es hier nur als Referenz.
quelle
Ich mag
np.dot
(Punktprodukt):quelle
Ein schöner Einzeiler:
Wenn es jedoch um Geschwindigkeit geht, würde ich empfehlen, an Ihrem Computer zu experimentieren. Ich habe festgestellt, dass die Verwendung von
math
Bibliothekensqrt
mit 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:
Läuft auf meiner Maschine
math_calc_dist
viel schneller alsnumpy_calc_dist
: 1,5 Sekunden gegenüber 23,5 Sekunden.Um einen messbaren Unterschied zwischen
fastest_calc_dist
und zu erhalten, musstemath_calc_dist
ich bisTOTAL_LOCATIONS
zu 6000. Dannfastest_calc_dist
dauert es ~ 50 Sekunden, während esmath_calc_dist
~ 60 Sekunden dauert.Sie können auch experimentieren
numpy.sqrt
undnumpy.square
obwohl beide langsamer waren als diemath
Alternativen auf meinem Computer.Meine Tests wurden mit Python 2.6.6 ausgeführt.
quelle
scipy.spatial.distance.cdist(p1, p2).sum()
. Das ist es.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.Sie können einfach die Vektoren subtrahieren und dann innerproduzieren.
Folgen Sie Ihrem Beispiel,
quelle
Mit
a
undb
wie Sie sie definiert haben, können Sie auch verwenden:quelle
Mit Python 3.8 ist das sehr einfach.
https://docs.python.org/3/library/math.html#math.dist
quelle
Hier ist ein prägnanter Code für die euklidische Entfernung in Python, wenn zwei Punkte in Python als Listen dargestellt werden.
quelle
Seit Python 3.8
Seit Python 3.8 enthält das
math
Modul die Funktionmath.dist()
.Siehe hier https://docs.python.org/3.8/library/math.html#math.dist .
quelle
Berechnen Sie den euklidischen Abstand für den mehrdimensionalen Raum:
quelle
quelle
quelle
Sie können die Formel leicht verwenden
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.
quelle
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.
quelle
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)))
quelle