Принятый ответ подходит для небольших наборов данных, но время его выполнения масштабируется как n**2
.Однако, как отмечает @payne, оптимальное решение может обеспечить масштабирование времени вычислений n*log(n)
.
Это оптимальное решение можно получить с помощью sklearn.neighbors.BallTree следующим образом.
import matplotlib.pyplot as plt
import numpy as np
from sklearn.neighbors import BallTree as tree
n = 10
dim = 2
xy = np.random.uniform(size=[n, dim])
# This solution is optimal when xy is very large
res = tree(xy)
dist, ids = res.query(xy, 2)
mindist = dist[:, 1] # second nearest neighbour
minid = np.argmin(mindist)
plt.plot(*xy.T, 'o')
plt.plot(*xy[ids[minid]].T, '-o')
Эта процедура хорошо масштабируется для очень больших наборов значений xy
и даже для больших размеров dim
(хотя пример иллюстрирует случай dim=2
).Полученный результат выглядит следующим образом:
Аналогичное решение можно получить с помощью scipy.spatial.cKDTree , заменив sklearn
импорт со следующим Scipy.Однако обратите внимание, что cKDTree
, в отличие от BallTree
, плохо масштабируется для больших размеров
from scipy.spatial import cKDTree as tree