您可以按照此答案中所示的方式预计算距离矩阵:
import numpy as np
X = np.array([84.04467948,60.,52.42447842,39.13555678])
Y = np.array([78.86529444,52.42447842,38.74910101,21.99846595])
dist = np.abs(X[:, np.newaxis] - Y)
现在你可以沿着一个轴计算最小值(我选择了1
,对应于找到每个X
的最近元素Y
):
potentialClosest = dist.argmin(axis=1)
这仍然可能包含重复项(在您的情况下为2)。要检查这一点,您可以通过使用np.unique
查找potentialClosest
中出现的所有Y
索引:
closestFound, closestCounts = np.unique(potentialClosest, return_counts=True)
现在,您可以通过检查
closestFound.shape[0] == X.shape[0]
来检查重复项。如果是这样,那么
potentialClosest
将包含每个元素在
X
中的伴侣。但在您的情况2中,一个元素会出现两次,因此
closestFound
将只有
X.shape[0]-1
个元素,而
closestCounts
不仅包含
1
,还有一个
2
。对于所有计数为
1
的元素,其伴侣已经找到。对于计数为
2
的两个候选者,您需要选择更接近的一个,而距离较大的那个的伴侣将是
Y
中不在
closestFound
中的那个元素。可以使用以下方法找到它:
missingPartnerIndex = np.where(
np.in1d(np.arange(Y.shape[0]), closestFound)==False
)[0][0]
你可以在循环中进行匹配(尽管可能有一些更好的方法,使用
numpy
)。这个解决方案相当丑陋,但是有效。非常欢迎任何改进建议。
partners = np.empty_like(X, dtype=int)
nonClosePartnerFound = False
for i in np.arange(X.shape[0]):
if closestCounts[closestFound==potentialClosest[i]][0]==1:
partners[i] = potentialClosest[i]
else:
if nonClosePartnerFound:
partners[i] = potentialClosest[i]
else:
if np.argmin(dist[:, potentialClosest[i]]) == i:
partners[i] = potentialClosest[i]
else:
partners[i] = missingPartnerIndex
nonClosePartnerFound = True
print(partners)
只有一个元素对不是紧密的时,这个答案才适用。如果不是这种情况,您需要定义如何找到多个非紧密元素的正确配对。不幸的是,这既不是非常通用的解决方案,也不是非常好的解决方案,但希望您能将其作为有用的起点。
x
和所有y
项之间的最小差异。获取总体最小差异的那个,将它们各自的项目弹出它们的列表并重复。一个递归函数。 - Ma0