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