Как вычислить евклидово расстояние с помощью NumPy?
У меня есть две точки в 3D-пространстве:
a = (ax, ay, az)
b = (bx, by, bz)
Мне нужно вычислить расстояние между ними:
dist = sqrt((ax-bx)^2 + (ay-by)^2 + (az-bz)^2)
Как я могу сделать это с помощью NumPy? Я уже создал массивы для этих точек:
import numpy
a = numpy.array((ax, ay, az))
b = numpy.array((bx, by, bz))
Как правильно рассчитать расстояние между этими двумя точками, используя возможности NumPy?
5 ответ(ов)
Это можно сделать следующим образом. Не могу сказать, насколько это быстро, но данный код не использует NumPy.
from math import sqrt
a = (1, 2, 3) # Первая точка данных
b = (4, 5, 6) # Вторая точка данных
print(sqrt(sum((x - y) ** 2 for x, y in zip(a, b))))
Обратите внимание, что я исправил код — в оригинале использовалось некорректное выражение для вычитания кортежей. Я изменил a - b
на (x - y)
внутри генератора, чтобы он работал правильно.
Вот краткий ответ на ваш вопрос:
Для вычисления расстояния между двумя точками a
и b
вы можете использовать следующий однострочник:
dist = numpy.linalg.norm(a - b)
Однако, если скорость имеет значение, я рекомендую провести эксперименты на вашем компьютере. На моем оборудовании функция sqrt
из библиотеки math
с оператором **
для возведения в квадрат работает значительно быстрее, чем решение в одну строку с использованием 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(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(TOTAL_LOCATIONS):
for j in range(TOTAL_LOCATIONS):
dist = fastest_calc_dist(p1[i], p2[j]) # измените эту строку для тестирования
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.
На самом деле, функция dist
из модуля matplotlib.mlab
действительно существует, но стоит отметить, что она не так удобна в использовании, как можно было бы ожидать. В современных версиях Matplotlib модуль mlab
считается устаревшим, и для вычисления расстояний между векторами рекомендуется использовать библиотеку NumPy.
Вот пример кода, который может быть более удобным для таких задач:
import numpy as np
a = np.array([1, 2, 3])
b = np.array([2, 3, 4])
# Вычисляем расстояние между векторами a и b
distance = np.linalg.norm(a - b)
print(distance)
В этом примере мы используем функцию np.linalg.norm
, чтобы вычислить евклидово расстояние между векторами a
и b
. Такой подход более "питонический" и является стандартом для работы с линейной алгеброй в Python.
Вы можете просто вычесть векторы, а затем выполнить их скалярное произведение.
В соответствии с вашим примером:
import numpy as np
a = np.array((xa, ya, za))
b = np.array((xb, yb, zb))
tmp = a - b
sum_squared = np.dot(tmp.T, tmp)
result = np.sqrt(sum_squared)
Этот код вычисляет евклидово расстояние между двумя векторами a
и b
в трехмерном пространстве. Сначала вычитаем вектор b
из вектора a
, затем используем функцию numpy.dot()
для вычисления суммы квадратов разностей, и в конце берем квадратный корень из полученной суммы, чтобы получить расстояние.
Если вы хотите вычислить расстояние между двумя точками в 3D-пространстве с помощью dot-продукта, то ваше решение выглядит корректным. Используя библиотеку NumPy, вы можете легко реализовать эту задачу.
Вот ваш код на Python с небольшими пояснениями:
import numpy as np
# Задаем координаты двух точек
a = np.array((xa, ya, za))
b = np.array((xb, yb, zb))
# Вычисляем расстояние между точками a и b
distance = np.sqrt(np.dot(a - b, a - b))
В этом коде мы сначала создаем два массива a
и b
, которые представляют собой координаты двух точек в 3D-пространстве. Затем мы вычисляем разность между этими двумя векторами (a - b
) и применяем np.dot
для вычисления скалярного произведения. Умножив результат на себя, а затем вычислив квадратный корень (np.sqrt
), мы получаем расстояние между точками a
и b
.
Так что ваш метод с использованием np.dot
абсолютно правильный и позволяет эффективно вычислить расстояние!
Как вывести полный массив NumPy без обрезки?
Сохранить график в файл изображения вместо его отображения
Преобразование списка словарей в DataFrame pandas
Как отсортировать список/кортеж списков/кортежей по элементу на заданном индексе
Что такое Python egg?