您可以使用np.in1d
函数查找数组a
中与数组b
相同的元素。
要查找索引,请使用一次调用np.where
函数:
In [34]: a = array([1,2,3,4,5])
In [35]: b = array([2,4,7])
In [36]: np.in1d(a, b)
Out[38]: array([False, True, False, True, False], dtype=bool)
In [39]: np.where(np.in1d(a, b))
Out[39]: (array([1, 3]),)
因为
a
和
b
已经排好序,所以你可以使用
In [57]: np.searchsorted(b, a, side='right') != np.searchsorted(b, a, side='left')
Out[57]: array([False, True, False, True, False], dtype=bool)
对于大的a
和b
,使用searchsorted
可能比np.in1d(a, b)
更快:
import numpy as np
a = np.random.choice(10**7, size=10**6, replace=False)
a.sort()
b = np.random.choice(10**7, size=10**5, replace=False)
b.sort()
In [53]: %timeit np.in1d(a, b)
10 loops, best of 3: 176 ms per loop
In [54]: %timeit np.searchsorted(b, a, side='right') != np.searchsorted(b, a, side='left')
10 loops, best of 3: 106 ms per loop
Jaime 和 Divakar 建议了一些重要的改进方法来解决上述问题。以下是一些测试这些方法是否返回相同结果的代码,以及一些基准测试:
import numpy as np
a = np.random.choice(10**7, size=10**6, replace=False)
a.sort()
b = np.random.choice(10**7, size=10**5, replace=False)
b.sort()
def using_searchsorted(a, b):
return (np.where(np.searchsorted(b, a, side='right')
!= np.searchsorted(b, a, side='left')))[0]
def using_in1d(a, b):
return np.where(np.in1d(a, b))[0]
def using_searchsorted_divakar(a, b):
idx1 = np.searchsorted(a,b,'left')
idx2 = np.searchsorted(a,b,'right')
out = idx1[idx1 != idx2]
return out
def using_jaime_mask(haystack, needle):
idx = np.searchsorted(haystack, needle)
mask = idx < haystack.size
mask[mask] = haystack[idx[mask]] == needle[mask]
idx = idx[mask]
return idx
expected = using_searchsorted(a, b)
for func in (using_in1d, using_searchsorted_divakar, using_jaime_mask):
result = func(a, b)
assert np.allclose(expected, result)
In [29]: %timeit using_jaime_mask(a, b)
100 loops, best of 3: 13 ms per loop
In [28]: %timeit using_searchsorted_divakar(a, b)
10 loops, best of 3: 21.7 ms per loop
In [26]: %timeit using_searchsorted(a, b)
10 loops, best of 3: 109 ms per loop
In [27]: %timeit using_in1d(a, b)
10 loops, best of 3: 173 ms per loop
np.searchsorted(b, a, side='left')
以获取实际的索引。 - Divakarnp.where
来获取相对于a
的索引。 - unutbuidx1 = np.searchsorted(a,b,'left'); idx2 = np.searchsorted(a,b,'right'); out = idx1[idx1 != idx2]
。也许可以工作? - Divakar