2014-12-04 4 views
2

Я немного искал и нашел сопоставимые вопросы/ответы, но ни один из них не вернул мне правильные результаты.Рассчитать средневзвешенное эвклидовое расстояние между значениями в numpy

Ситуация: У меня есть массив с некоторым количеством сгустков значений == 1, в то время как остальная часть ячеек устанавливаются в ноль. Каждая ячейка представляет собой квадрат (ширина = высота). Теперь я хочу рассчитать среднее расстояние между всеми 1 значениями. Формула должна быть такой: d = sqrt (((x2 - x1)*size)**2 + ((y2 - y1)*size)**2)

Пример:

import numpy as np 
from scipy.spatial.distance import pdist 

a = np.array([[1, 0, 1], 
       [0, 0, 0], 
       [0, 0, 1]]) 

# Given that each cell is 10m wide/high 
val = 10 
d = pdist(a, lambda u, v: np.sqrt((((u-v)*val)**2).sum())) 
d 
array([ 14.14213562, 10.  , 10.  ]) 

После этого я бы вычислить среднее через d.mean(). Однако результат в d явно неверен, поскольку расстояние между ячейками в верхней строке должно быть уже 20 (две скрещенные ячейки * 10). Что-то не так с моей формулой, математикой или подходом?

ответ

3

Вам нужны фактические координаты ненулевых маркеров, для вычисления расстояния между ними:

>>> import numpy as np 
>>> from scipy.spatial.distance import squareform, pdist 
>>> a = np.array([[1, 0, 1], 
...    [0, 0, 0], 
...    [0, 0, 1]]) 
>>> np.where(a) 
(array([0, 0, 2]), array([0, 2, 2])) 
>>> x,y = np.where(a) 
>>> coords = np.vstack((x,y)).T 
>>> coords 
array([[0, 0], # That's the coordinate of the "1" in the top left, 
     [0, 2], # top right, 
     [2, 2]]) # and bottom right. 

Далее вы хотите, чтобы вычислить расстояние между этими точками. Вы можете использовать pdist для этого, например, так:

>>> dists = pdist(coords) * 10 # Uses the Euclidean distance metric by default. 
>>> squareform(dists) 
array([[ 0.  , 20.  , 28.28427125], 
     [ 20.  , 0.  , 20.  ], 
     [ 28.28427125, 20.  , 0.  ]]) 

В этой последней матрицы, вы найдете (выше диагонали), то расстояние между каждой отмеченной точкой в ​​a и другой координате. В этом случае у вас было 3 координаты, поэтому он дает расстояние между узлом 0 (a[0,0]) и узлом 1 (a[0,2]), узлом 0 и узлом 2 (a[2,2]) и, наконец, между узлом 1 и узлом 2. Поставить его в разные слова, если S = squareform(dists), то S[i,j] возвращает расстояние между координатами по строке icoords и строке j.

Просто значение в верхнем треугольнике этой последней матрицы также присутствует в переменной dist, из которого можно вывести среднее значение легко, без необходимости выполнения относительно дорогой расчет squareform (как показано здесь только для демонстрационных целей):

>>> dists 
array([ 20.  , 28.2842712, 20.  ]) 
>>> dists.mean() 
22.761423749153966 

замечание, что ваше вычисленное решение «выглядит» почти правильно (кроме 2 раза), из примера вы выбрали. Что делает pdist, требуется ли евклидово расстояние между первой точкой в ​​n-мерном пространстве, а второе, а затем между первым и третьим и так далее. В вашем примере это означает, что он вычисляет расстояние между точкой в ​​строке 0: эта точка имеет координаты в трехмерном пространстве, заданные [1,0,1]. Второй пункт - [0,0,0]. Евклидово расстояние между этими двумя sqrt(2)~1.4. Затем расстояние между первой и третьей координатами (последняя строка в a) составляет всего 1. Наконец, расстояние между 2-й координатой (строка 1: [0,0,0]) и 3-я (последняя строка, строка 2: [0,0,1]) также равна 1. Поэтому помните, что pdist интерпретирует свой первый аргумент как стек координат в n-мерном пространстве, n - количество элементов в кортеже каждого узла.

+0

Эй, спасибо за совет. Пока я не использовал команды np.where и np.vstack, поэтому я попробую это.К сожалению, он по-прежнему возвращает неправильные значения для моего набора данных примера (который намного больше, а сгустки * 1 * сильно искажены и имеют неправильную форму). Я предполагаю, что что-то с формулой еще не совсем верно, но я буду исследовать – Curlew

+0

@Curlew, как вы описали проблему, вы сделали так, чтобы каждый «скопление» представляло собой единственный маркер, один элемент (1) окруженный нулями. Если, однако, у вас есть фактический «скопление», например, связанная область 1, например, представляет местоположение частицы в реальной жизни, тогда вы должны взять центр этого скопления. Но это меняет ваш вопрос, поэтому вы можете подумать о том, чтобы задать новый вопрос и предоставить более подробную информацию о фактическом наборе данных (возможно, это двоичная фотография организмов?). –

Смежные вопросы