Как рассчитать евклидово расстояние с помощью NumPy? - PullRequest
423 голосов
/ 09 сентября 2009

У меня есть две точки в 3D:

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

И я хочу рассчитать расстояние:

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

Какой лучший способ сделать это с NumPy или с Python в целом? У меня есть:

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

Ответы [ 18 ]

5 голосов
/ 28 декабря 2016

Имея a и b, как вы их определили, вы также можете использовать:

distance = np.sqrt(np.sum((a-b)**2))
5 голосов
/ 13 ноября 2010

Хороший однострочник:

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

Однако, если скорость имеет значение, я бы порекомендовал поэкспериментировать на вашей машине. Я обнаружил, что использование sqrt библиотеки *1005* с оператором ** для квадрата намного быстрее на моей машине, чем однострочное решение NumPy.

Я провел свои тесты с помощью этой простой программы:

#!/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

На моей машине math_calc_dist работает намного быстрее, чем numpy_calc_dist: 1,5 секунды против 23,5 секунды .

Чтобы измерить разницу между fastest_calc_dist и math_calc_dist, мне пришлось увеличить TOTAL_LOCATIONS до 6000. Затем fastest_calc_dist занимает ~ 50 секунд , а math_calc_dist - ~ 60 секунд .

Вы также можете поэкспериментировать с numpy.sqrt и numpy.square, хотя оба варианта были медленнее, чем альтернативы math на моей машине.

Мои тесты запускались с Python 2.6.6.

3 голосов
/ 17 мая 2016

Вот краткий код евклидова расстояния в Python с учетом двух точек, представленных в виде списков в Python.

def distance(v1,v2): 
    return sum([(x-y)**2 for (x,y) in zip(v1,v2)])**(0.5)
1 голос
/ 19 апреля 2018

Вы можете легко использовать формулу

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

, которая на самом деле не более чем использует теорему Пифагора для вычисления расстояния, добавляя квадраты Δx, Δy и Δz и укореняя результат.

1 голос
/ 22 февраля 2018
import math

dist = math.hypot(math.hypot(xa-xb, ya-yb), za-zb)
1 голос
/ 10 февраля 2018
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)
1 голос
/ 14 июня 2017

Рассчитайте евклидово расстояние для многомерного пространства:

 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
0 голосов
/ 26 июля 2018

Сначала найдите разницу двух матриц. Затем примените поэлементное умножение с помощью команды умножения numpy. После этого найдите суммирование умноженной на элемент новой матрицы. Наконец, найдите квадратный корень суммы.

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
...