从排序的向量中查找值,这些值也存在于另一个排序的向量中

时间:2014-11-25 18:59:29

标签: python numpy scipy

假设我有两个已排序的向量(1D numpy ndarrays)A和B.我想找到向量A中的哪些值也存在于向量B中。这将成为某个函数的瓶颈所以我希望制作尽可能快。有一个函数numpy.in1d,它完全符合我的需要。可以通过告诉函数向量中的值是唯一的这一事实来提升它。好的,很好。但排序值怎么样?我相信知道值的排序可以进一步提高性能,因为它会是复杂度O(1)。但是没有理由告诉numpy.in1d矢量是排序的......还是有任何替代或技巧可以帮助我?

2 个答案:

答案 0 :(得分:2)

np.searchsorted返回应放置相应值的位置,而不会破坏排序。如果你的“haystack”数组包含该值,它将在那里。您只需要将这些位置的值与针进行比较。但要注意越界访问:在haystack中大于最大值的针将生成index == len(haystack)并生成IndexError。您可以使用np.take(..., mode='clip')返回此类值的最大值(并且它将无法通过相等测试)。

In [14]: haystack = np.array([1,2,4,5,8])

In [15]: needles = np.array([0,1,3,4,7,8,9])

In [16]: haystack.take(np.searchsorted(haystack, needles), mode='clip')
Out[16]: array([1, 1, 4, 4, 8, 8, 8])

In [17]: haystack.take(np.searchsorted(haystack, needles), mode='clip') == needles
Out[17]: array([False,  True, False,  True, False,  True, False], dtype=bool)

In [18]: needles[haystack.take(np.searchsorted(haystack, needles), mode='clip') == needles]
Out[18]: array([1, 4, 8])

如果您希望needles中的大量元素大于haystack.max(),则可能需要在搜索之前修剪needles以避免在无关元素上浪费空间

needles = needles[needles <= haystack.max()]

甚至更快的变种

needles = needles[:np.searchsorted(needles, haystack.max(), side='right')]

编辑:此解决方案为O(N*logM)N = len(needles), M = len(haystack),但它没有使用针本身已排序的事实。您可以在O(N + M)中的Cython / C中执行此操作,这对于大型(r)N来说会更快。

答案 1 :(得分:0)

也许你可以创建每个向量的集合,然后在集合上使用相交。

我认为向量应该允许构建它们,例如:

a = set(vectorA)
b = set(vectorB)
commons = a.intersection(b)