【问题标题】:compute all n-th closest points of all points in a dataset计算数据集中所有点的所有第 n 个最近点
【发布时间】:2021-12-27 19:47:05
【问题描述】:

我在飞机上有 1000 个点的数据集。我表示 P 中所有可能的点对并计算所有可能对的距离。 我要做的是:对于给定的n,计算P中所有点p的所有第n个最近点。

我之前做过的:

P_pairs = [((33, 9), (34, 13)), ((33, 9), (62, 119)), ((33, 9), (33, 7)), ((33, 9), (48, 123)), ...]

listofdistances =  [{'((33, 9), (34, 13))': 4.123105625617661}, {'((33, 9), (62, 119))': 113.75851616472501}, {'((33, 9), (33, 7))': 2.0}, ...]

在这种情况下,我被困在对listofdistances 进行排序,这样对于每个点,都有最小的 n 距离作为剩余的值。

也许我必须直接计算第 n 个最近的点,而不是计算点的所有距离。但我不知道怎么做。

【问题讨论】:

  • P 似乎有一个所有点配对的列表。不应该是长度为 1000 的 [(33, 9), (34, 13), (62, 119), ...] 吗?
  • @Reti43 是的,没错!

标签: python sorting nearest-neighbor euclidean-distance


【解决方案1】:
P = [(33, 9), (34, 13), (62, 119), (33, 7), (48, 123)]
P = np.array(P)

x, y = P[:,0], P[:,1]
# Create a distance table of point (row) vs point (column)
dist = np.sqrt((x - x[:,None])**2 + (y - y[:,None])**2)
# The diagonals are 0, as the distance of a point to itself is 0,
# but we want that to have a large value so it comes last in sorting
np.fill_diagonal(dist, np.inf)
# Get the sorted index for each row
idx = dist.argsort(axis=1)

现在,如果您想要第 n 个最近的邻居,并且 n = 3,您可以通过 idx = idx[:,:3] 得到它。对于第一点,你现在可以做

P[0]             # the point itself
P[idx[0]]        # its nearest neighbours
dist[0,idx[0]]   # their distances

【讨论】:

  • 谢谢你,这对我了解 numpy 的可能性有很大帮助
【解决方案2】:

创建一个所有可能对的列表,然后创建一个以距离为值的单键字典列表,这确实会让人头疼。我会改为矢量化这项工作并使用 numpy。

import numpy as np

P = np.array([(33, 9), (34, 13), (62, 119), ...])

# Finds the n closest points to p in P
def n_closest_points(p, P, n)
    p_vector = np.tile(p, (len(P), 1))
    dists = np.linalg.norm(P-p_vector, axis=1)
    sorted_dists = np.sort(dists)

    # Exclude the 0th element as the distance from p to itself is 0
    return sorted_dists[1:n+1] 

【讨论】:

  • 我没有使用 numpy...谢谢!所以你会建议,我为所有 p 运行该函数?
  • 如果您需要获取P 中每个pn 最接近点,可以。只需运行该函数for p in P