我们可以使用
np.searchsorted
来提高性能,特别是在查找数组具有排序唯一值的情况下更为明显。
def intersect1d_searchsorted(A,B,assume_unique=False):
if assume_unique==0:
B_ar = np.unique(B)
else:
B_ar = B
idx = np.searchsorted(B_ar,A)
idx[idx==len(B_ar)] = 0
return A[B_ar[idx] == A]
那个assume_unique
标志使其适用于通用情况和B
是唯一且已排序的特殊情况。
示例运行 -
In [89]: A = np.array([10,4,6,7,1,5,3,4,24,1,1,9,10,10,18])
...: B = np.array([1,4,5,6,7,8,9])
In [90]: intersect1d_searchsorted(A,B,assume_unique=True)
Out[90]: array([4, 6, 7, 1, 5, 4, 1, 1, 9])
在两种情况下,与另一个基于向量化的np.in1d
解决方案比较大的数组的时间 -
In [103]: A = np.random.randint(0,10000,(1000000))
In [104]: B = np.random.randint(0,10000,(1000000))
In [105]: %timeit A[np.in1d(A, B)]
...: %timeit A[np.in1d(A, B, assume_unique=False)]
...: %timeit intersect1d_searchsorted(A,B,assume_unique=False)
1 loop, best of 3: 197 ms per loop
10 loops, best of 3: 190 ms per loop
10 loops, best of 3: 151 ms per loop
In [106]: B = np.unique(np.random.randint(0,10000,(5000)))
In [107]: %timeit A[np.in1d(A, B)]
...: %timeit A[np.in1d(A, B, assume_unique=True)]
...: %timeit intersect1d_searchsorted(A,B,assume_unique=True)
10 loops, best of 3: 130 ms per loop
1 loop, best of 3: 218 ms per loop
10 loops, best of 3: 80.2 ms per loop
assume_unique
设置为True
,则np.intersect1d
似乎稍微更快一些。我不确定确切的原因是什么,但可能是因为它需要进行较少的比较。 - Alex Riley