Сортировка массива точек D по расстоянию до контрольной точки - PullRequest
0 голосов
/ 22 апреля 2020

У меня есть контрольная точка p_ref, сохраненная в массиве numpy с формой (1024,), что-то вроде:

print(p_ref)
>>> array([ p1,  p2,  p3, ..., p_n])

У меня также есть массив numpy A_points с формой (1024,5000), содержащей 5000 точек, каждая из которых имеет 1024 размера, например p_ref. Моя проблема: Я бы хотел отсортировать точки в A_points по их (евклидовому) расстоянию до p_ref!

Как я могу это сделать? Я читал о scipy.spatial.distance.cdist и scipy.spatial.KDTree, но они оба делали не то, что я хотел, и когда я попытался объединить их, я запутался. Спасибо!


Для справки и согласованности предположим:

p_ref = np.array([0,1,2,3])
A_points = np.reshape(np.array([10,3,2,13,4,5,16,3,8,19,4,11]), (4,3))

Ожидаемый результат:

array([[ 3,  2, 10],
       [ 4,  5, 13],
       [ 3,  8, 16],
       [ 4, 11, 19]])

Ответы [ 2 ]

1 голос
/ 22 апреля 2020

Вы можете сделать что-то вроде этого -

A_points[:,np.linalg.norm(A_points-p_ref[:,None],axis=0).argsort()]

Другой с np.einsum, который должен быть более эффективным, чем np.linalg.norm -

d = A_points-p_ref[:,None]
out = A_points[:,np.einsum('ij,ij->j',d,d).argsort()]

Дальнейшая оптимизация для использования быстрой матрицы- умножение для замены последнего шага -

A_points[:,((A_points**2).sum(0)+(p_ref**2).sum()-2*p_ref.dot(A_points)).argsort()]
1 голос
/ 22 апреля 2020

РЕДАКТИРОВАТЬ: Обновлено по предложениям ОП.

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

A_sorted = sorted( A_points.T, key = lambda x: np.linalg.norm(x - p_ref ) )
A_sorted = np.reshape(A_sorted, (3,4)).T
...