【发布时间】:2021-12-01 17:33:51
【问题描述】:
我有两组 n 点,作为 Numpy 数组,以随机顺序排列。我必须根据距离 (L2) 将两个列表之间的点关联起来,以便 list1 中的每个点都获得一个且唯一的对应点,即距离 list2 最接近的点。
我的问题:就计算时间而言,最快的方法是什么?
现在,我计算对称交叉范数矩阵(使用 scipy.spatial.distance_matrix)并通过循环从那里对点进行排序,以找到整个矩阵中的最低范数。然后删除相应的行和列并迭代直到矩阵为空。我想知道是否有已知的更快的方法来做到这一点。
[编辑]:这是我得到的代码和示例
import numpy as np
import numpy.ma as ma
import matplotlib.pyplot as plt
from scipy.spatial import distance_matrix
rng = np.random.default_rng()
lst1 = rng.random((10, 2))
lst2 = lst1 + 0.1 * rng.standard_normal(lst1.shape) # rng.random((10, 2))
mask = np.zeros((len(lst1), len(lst2)), dtype=bool)
dst = ma.array(distance_matrix(lst1, lst2), mask=mask)
ord_lst1 = []
ord_lst2 = []
for i in range(min(len(lst1), len(lst2))):
index = np.unravel_index(np.argmin(dst), shape=dst.shape)
ord_lst1.append(lst1[index[0], :])
ord_lst2.append(lst2[index[1], :])
dst[index[0], :] = ma.masked
dst[:, index[1]] = ma.masked
fig = plt.figure()
plt.grid(True)
plt.scatter(x=lst1[:, 0], y=lst1[:, 1], label="list1")
plt.scatter(x=lst2[:, 0], y=lst2[:, 1], label="list2")
for p1, p2 in zip(ord_lst1, ord_lst2):
plt.plot((p1[0], p2[0]), (p1[1], p2[1]), "--", color="black")
plt.legend()
如您所见,两个非常间隔的点之间的巨大关联可能会令人不安。但是,list1 在 (0.4, 0.6) 中的点与右上角的 list2 最接近,因此建立了关联并排除了这两个点的进一步关联。
谢谢:)
【问题讨论】:
-
请添加一些数据
-
如果 list2 中的某个点与某些 list1 点最接近怎么办? (您的图片没有显示这种模棱两可的情况)。在这种情况下,您似乎需要某种加权匹配。
-
@DaniMesejo:此处的数据是使用以下方法生成的:rng = np.random.default_rng() lst1 = rng.random((10, 2)) lst2 = lst1 + 0.03 * rng.standard_normal(lst1.形状)
-
@MBo:当我寻找一个一对一的关联表时,对于 list1 中的给定点,list2 中的最近点应与其关联,因此无法将这些点与其他点关联.就好像我们首先关联最接近的,然后他们将它们从关联过程中取出。
-
list1: [1,0],[0,0] list2: [0,1], [1,2]。如果我们从左到右遍历 list1,我们有 0-1、1-0 索引对应,如果我们从右到左遍历,我们有 0-0、1-1 对应(看起来更直观)
标签: python algorithm numpy geometry