【发布时间】:2013-02-28 02:17:25
【问题描述】:
我有两个包含浮点值的 numpy 数组 x 和 y。对于x 中的每个值,我想在y 中找到最接近的元素,而不重复使用y 中的元素。输出应该是从 x 到 y 的元素索引的 1-1 映射。这是一种依赖排序的坏方法。它从列表中删除每个配对的元素。不排序会很糟糕,因为配对将取决于原始输入数组的顺序。
def min_i(values):
min_index, min_value = min(enumerate(values),
key=operator.itemgetter(1))
return min_index, min_value
# unsorted elements
unsorted_x = randn(10)*10
unsorted_y = randn(10)*10
# sort lists
x = sort(unsorted_x)
y = sort(unsorted_y)
pairs = []
indx_to_search = range(len(y))
for x_indx, x_item in enumerate(x):
if len(indx_to_search) == 0:
print "ran out of items to match..."
break
# until match is found look for closest item
possible_values = y[indx_to_search]
nearest_indx, nearest_item = min_i(possible_values)
orig_indx = indx_to_search[nearest_indx]
# remove it
indx_to_search.remove(orig_indx)
pairs.append((x_indx, orig_indx))
print "paired items: "
for k,v in pairs:
print x[k], " paired with ", y[v]
我更喜欢不先对元素进行排序,但如果它们已排序,那么我想获取原始未排序列表unsorted_x、unsorted_y 中的索引。在 numpy/scipy/Python 或使用 pandas 中执行此操作的最佳方法是什么?谢谢。
编辑:澄清一下,我并不是要找到所有元素的最佳拟合(例如,不是最小化距离总和),而是要找到每个元素的最佳拟合,如果是这样就可以了有时以牺牲其他元素为代价。我假设y 通常比x 大得多,与上面的示例相反,因此y 中x 的每个值通常都有很多非常好的拟合,我只想有效地找到那个。
有人可以为此展示 scipy kdtrees 的示例吗?文档很少
kdtree = scipy.spatial.cKDTree([x,y])
kdtree.query([-3]*10) # ?? unsure about what query takes as arg
【问题讨论】:
-
我认为用二分法查找索引的排序可能是你最好的选择。
-
@mgilton: scipy/numpy 中有内置的二分搜索算法吗?
-
在我看来,您需要
np.sort、np.argsort和np.searchsorted的组合来完成它。 -
@Jaime,不知道你的意思,你可以得到你用它查询的集合之外的点的 k 最近邻。
tree = KDTree(x[:,None]); tree.query(y[:,None], k=1)为所有y找到最近的x(基于二次范数,您可以更改它)。