Вычислить массив numpy по парному евклидову расстоянию, кроме себя

редактировать: этот вопрос касается не только расчета расстояний, а наиболее эффективного способа перебора массива numpy, указывающего, что для индекса i все сравнения должны выполняться с остальной частью массива, пока второй индекс не i.

У меня есть массив numpy со столбцами (X, Y, ID) и я хочу сравнить каждый элемент с другим элементом, но не с самим собой. Итак, для каждой координаты X, Y я хочу вычислить расстояние друг от друга до координат X, Y, но не до себя (где расстояние = 0).

Вот что у меня есть - должен быть более "тупой" способ написать это.

import math, arcpy
# Point feature class
fc = "MY_FEATURE_CLASS"
# Load points to numpy array: (X, Y, ID)
npArray = arcpy.da.FeatureClassToNumPyArray(fc,["SHAPE@X","SHAPE@Y","OID@"])
for row in npArray:
    for row2 in npArray:
        if row[2] != row2[2]:
            # Pythagoras's theorem
            distance = math.sqrt(math.pow((row[0]-row2[0]),2)+math.pow((row[1]-row2[1]),2))

Очевидно, я тупой новичок. Я не удивлюсь, обнаружив это дубликат, но у меня нет словарного запаса, чтобы найти ответ. Любая помощь приветствуется!


person phloem7    schedule 18.03.2015    source источник
comment
Вы можете посмотреть на scipy.spatial.distance.pdist.   -  person user2357112 supports Monica    schedule 18.03.2015
comment
возможный дубликат Вычисление евклидова расстояния для numpy в python   -  person Oliver W.    schedule 19.03.2015
comment
Обратите внимание, что во многих геометриях d(x, y) = 0 тогда и только тогда, когда x = y, поэтому вы можете пропустить эту проверку и разобраться с нулями позже. Не обращайте внимания на этот комментарий, если вы имеете дело с вычислением расстояния при неинъективном отображении - я только что заметил, что вы обсуждаете функции в своем коде, что предполагает, что это может иметь место.   -  person Patrick McLaren    schedule 19.03.2015
comment
@PatrickMcLaren Может быть. Основная цель вопроса - найти ближайшую другую геометрию к данной геометрии. Если я оставлю нули, то я ищу вторую ближайшую геометрию к каждой геометрии, которая кажется более сложной.   -  person phloem7    schedule 19.03.2015
comment
Что ж, если вы хотите использовать scipy, то комментарий пользователя @user2357112 должен помочь. Если нет, вы можете использовать понимание списка, скажем, distances = [dist(x, y) for x in npArray for y in npArray if x != y], где dist — некоторая метрика.   -  person Patrick McLaren    schedule 19.03.2015
comment
С точки зрения математики вы можете построить трехмерный тензор с размерами NxNx2 из двух матриц размером Nx2, с помощью так называемой матрицы broadcasting Nx2 до тензора NxNx2, получить ее транспонированную версию и вычесть их, а затем вычислить норму L2 по третьей оси. Тогда, я думаю, у вас будет ровно матрица парных расстояний.   -  person Ben Usman    schedule 19.03.2015
comment
@user2312518 user2312518 Я использую cKDTree, который входит в SciPy, для очень эффективного выполнения такого рода задач, кажется, намного быстрее, чем расчет всех расстояний   -  person Saullo G. P. Castro    schedule 19.03.2015


Ответы (2)


Используя pdist SciPy вы можете написать что-то вроде

from scipy.spatial.distance import pdist, squareform

distances = squareform(pdist(npArray, lambda a,b: np.sqrt((a[0]-b[0])**2 + (a[1]-b[1])**2)))

pdist будет вычислять парные расстояния, используя пользовательскую метрику, которая игнорирует 3-ю координату (которая в данном случае является вашим идентификатором). squareform превращает это в более удобочитаемую матрицу, так что distances[0,1] дает расстояние между 0-й и 1-й строками.

person wht    schedule 14.06.2019

Каждая строка X представляет собой трехмерный экземпляр данных или точку. Выход pairwisedist[i, j] - это расстояние X[i, :] и X[j, :]

X = np.array([[6,1,7],[10,9,4],[13,9,3],[10,8,15],[14,4,1]])
a = np.sum(X*X,1)
b = np.repeat( a[:,np.newaxis],5,axis=1)
pairwisedist = b + b.T -2* X.dot(X.T)
person Mohammad R. Moosavi    schedule 29.12.2019