Как найти два ближайших массива numpy из нескольких массивов numpy?

#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. Работает нормально. Это была моя ошибка.