Как вычислить евклидово расстояние с помощью 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
Как извлечь частоту, связанную с FFT значениями в Python?
Цветовой график 2D массива в matplotlib
Преобразование байтового массива обратно в массив numpy
Взвешенный процентиль с помощью numpy