Многомерное евклидово расстояние в Python - PullRequest
8 голосов
/ 23 февраля 2012

Я хочу вычислить евклидово расстояние в нескольких измерениях (24 измерения) между двумя массивами.Я использую Numpy-Scipy.

Вот мой код:

import numpy,scipy;

A=numpy.array([116.629, 7192.6, 4535.66, 279714, 176404, 443608, 295522, 1.18399e+07, 7.74233e+06, 2.85839e+08, 2.30168e+08, 5.6919e+08, 168989, 7.48866e+06, 1.45261e+06, 7.49496e+07, 2.13295e+07, 3.74361e+08, 54.5, 3349.39, 262.614, 16175.8, 3693.79, 205865]);

B=numpy.array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 151246, 6795630, 4566625, 2.0355328e+08, 1.4250515e+08, 3.2699482e+08, 95635, 4470961, 589043, 29729866, 6124073, 222.3]);

Тем не менее, я использовал scipy.spatial.distance.cdist(A[numpy.newaxis,:],B,'euclidean') для вычисления расстояния Евклида.*

raise ValueError('XB must be a 2-dimensional array.');

Кажется, я этого не понимаю.

Я посмотрел scipy.spatial.distance.pdist но не понимаю, как его использовать?

Есть ли другой лучший способ сделать это?

Ответы [ 6 ]

12 голосов
/ 23 февраля 2012

Возможно scipy.spatial.distance.euclidean?

Примеры

>>> from scipy.spatial import distance
>>> distance.euclidean([1, 0, 0], [0, 1, 0])
1.4142135623730951
>>> distance.euclidean([1, 1, 0], [0, 1, 0])
1.0
10 голосов
/ 23 февраля 2012

Используйте

numpy.sqrt(numpy.sum((A - B)**2))

или более просто

numpy.linalg.norm(A - B)
7 голосов
/ 23 февраля 2012

A и B - это 2 точки в 24-мерном пространстве.Вы должны использовать scipy.spatial.distance.euclidean.

Док.

scipy.spatial.distance.euclidean(A, B)
4 голосов
/ 23 февраля 2012

Помимо уже упомянутых способов вычисления евклидова расстояния, вот один, который близок к вашему исходному коду:

scipy.spatial.distance.cdist([A], [B], 'euclidean')

или

scipy.spatial.distance.cdist(np.atleast_2d(A), np.atleast_2d(B), 'euclidean')

Возвращает 1 × 1 np.ndarray, удерживая расстояние L2.

3 голосов
/ 13 декабря 2017

Так как все вышеприведенные ответы относятся к numpy и или scipy, я просто хотел отметить, что можно сделать что-то действительно простое с помощью Reduce

def n_dimensional_euclidean_distance(a, b):
   """
   Returns the euclidean distance for n>=2 dimensions
   :param a: tuple with integers
   :param b: tuple with integers
   :return: the euclidean distance as an integer
   """
   dimension = len(a) # notice, this will definitely throw a IndexError if len(a) != len(b)

   return sqrt(reduce(lambda i,j: i + ((a[j] - b[j]) ** 2), range(dimension), 0))

Суммирует все пары (a [j] - b [j]) ^ 2 для всех j в количестве измерений (обратите внимание, что для простоты это не поддерживает n <2-мерное расстояние). </p>

1 голос
/ 15 января 2019

Начиная с Python 3.8, вы можете использовать модуль math стандартной библиотеки и его новую функцию dist, которая возвращает евклидово расстояние между двумя точками (задается как кортеж)координат):

from math import dist

dist((1, 0, 0), (0, 1, 0)) # 1.4142135623730951

А при работе со списками вместо кортежей:

dist(tuple([1, 0, 0]), tuple([0, 1, 0]))
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...