Вам нужны фактические координаты ненулевых маркеров, для вычисления расстояния между ними:
>>> 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]
возвращает расстояние между координатами по строке i
coords
и строке 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
- количество элементов в кортеже каждого узла.
Эй, спасибо за совет. Пока я не использовал команды np.where и np.vstack, поэтому я попробую это.К сожалению, он по-прежнему возвращает неправильные значения для моего набора данных примера (который намного больше, а сгустки * 1 * сильно искажены и имеют неправильную форму). Я предполагаю, что что-то с формулой еще не совсем верно, но я буду исследовать – Curlew
@Curlew, как вы описали проблему, вы сделали так, чтобы каждый «скопление» представляло собой единственный маркер, один элемент (1) окруженный нулями. Если, однако, у вас есть фактический «скопление», например, связанная область 1, например, представляет местоположение частицы в реальной жизни, тогда вы должны взять центр этого скопления. Но это меняет ваш вопрос, поэтому вы можете подумать о том, чтобы задать новый вопрос и предоставить более подробную информацию о фактическом наборе данных (возможно, это двоичная фотография организмов?). –