#python #numpy
#python #numpy
Вопрос:
У меня есть несколько массивов numpy, и я хочу сравнить их и найти ближайший массив для данного массива. Я мог бы вычислить расстояние между этими массивами с помощью https://docs.scipy.org/doc/scipy/reference/generated/scipy.spatial.distance.cdist.html. Однако есть ли способ найти два ближайших массива из нескольких массивов numpy?
Для массивов, которые я получил print(arr.shape)
, дает (300,)
Ответ №1:
Чтобы найти два ближайших, вам нужно вычислить матрицу расстояний, затем найти минимум в этой матрице, чтобы получить координаты, которые находятся ближе всего друг от друга (используя матрицу, вы получите индексы координат).
from scipy.spatial import distance
import numpy as np
coords = np.array([
(35.0456, -85.2672),
(35.1174, -89.9711),
(35.9728, -83.9422),
(36.1667, -86.7833)
])
distances = distance.cdist(coords, coords, 'euclidean')
# If you don't do that then the distance to self will always
# be the min. distance in the matrix (always 0):
np.fill_diagonal(distances, np.inf)
min_index = (np.argmin(distances))
closest = np.unravel_index(min_index, distances.shape)
Как только вы определили closest
индексы, вы можете получить всю необходимую информацию о вашей паре ближайших координат:
print(f"The two closest are {closest}")
print(f"They are at distance {distances[closest]}")
print(f"Resp. coordinates {coords[closest[0]]} and {coords[closest[1]]}")
Выводит:
The two closest are (0, 2)
They are at distance 1.6171965990565296
Resp. coordinates [ 35.0456 -85.2672] and [ 35.9728-83.9422]
Наконец, обратите внимание, что все эти входные данные тоже будут работать:
coords = np.array([ [35.0456, -85.2672], [35.1174, -89.9711] ])
arr1 = [35.0456, -85.2672]
arr2 = [35.1174, -89.9711]
coords = np.array([arr1, arr2])
Комментарии:
1. Насколько я понимаю, я думаю, что то, что вы опубликовали выше, заключается в поиске двух ближайших точек в заданном массиве. Но что мне нужно, так это найти два ближайших массива среди множества массивов (что-то вроде ответа @Horbaje)
2. Что это делает, так это находит самые близкие координаты (представленные массивами, или здесь кортежами, но это одно и то же) в массиве координат. Поэтому он находит ближайшие массивы в списке массивов.
3. Я отредактировал свой ответ и добавил детали для массивов массивов вместо массива кортежей.
Ответ №2:
Как насчет написания функции расстояния, а затем использования itertools для вычисления расстояния между парами списков?
Например:
a_1 = [0,3,4,5]
a_2 = [4,7,8,9]
a_3 = [12, 34, 44]
from itertools import combinations
def distance(list1, list2):
"""Distance between two vectors."""
squares = [(p-q) ** 2 for p, q in zip(list1, list2)]
return sum(squares) ** .5
distances = []
for pair in combinations([a_1, a_2, a_3], 2):
distances.append(pair)
distances.append(distance(list(pair[0]), list(pair[1])))
Результат:
[([0, 3, 4, 5], [4, 7, 8, 9]), 8.0, ([0, 3, 4, 5], [12, 34, 44]), 52.009614495783374, ([4, 7, 8, 9], [12, 34, 44]), 45.70557952810576]
Комментарии:
1. Имеющиеся у меня массивы numpy представляют собой векторные представления fasttext. Я попробовал то, что вы опубликовали, и для каждого расстояния я получаю 0.0. Почему это?
2. Функция distance предполагает, что элементы в вашем векторе являются целыми числами. Вы должны быть в состоянии выполнить преобразование. Например, с пониманием списка
a_1 = [ int(x) for x in a_1 ]
3. Работает нормально. Это была моя ошибка.