Python:检查一个NumPy数组是否包含另一个数组的任何元素

17
什么是检查一个numpy数组是否包含另一个数组中任何元素的最佳方法?
例如:
array1 = [10,5,4,13,10,1,1,22,7,3,15,9]
array2 = [3,4,9,10,13,15,16,18,19,20,21,22,23]`

如果array1包含array2中的任何一个值,则我希望获得True,否则获得False


2
使用np.any(np.in1d(array2, array1)) - Norman
3个回答

23

使用Pandas,你可以使用isin函数:

a1 = np.array([10,5,4,13,10,1,1,22,7,3,15,9])
a2 = np.array([3,4,9,10,13,15,16,18,19,20,21,22,23])

>>> pd.Series(a1).isin(a2).any()
True

使用NumPy的in1d函数(按照@Norman的评论):

>>> np.any(np.in1d(a1, a2))
True

对于像本例中的小数组,使用set的解决方案是明显的赢家。对于更大、不相似的数组(即没有重叠部分),Pandas和Numpy的解决方案更快。然而,np.intersect1d 在处理更大的数组时似乎表现超群。

小数组(12-13个元素)

%timeit set(array1) & set(array2)
The slowest run took 4.22 times longer than the fastest. This could mean that an intermediate result is being cached 
1000000 loops, best of 3: 1.69 µs per loop

%timeit any(i in a1 for i in a2)
The slowest run took 12.29 times longer than the fastest. This could mean that an intermediate result is being cached 
100000 loops, best of 3: 1.88 µs per loop

%timeit np.intersect1d(a1, a2)
The slowest run took 10.29 times longer than the fastest. This could mean that an intermediate result is being cached 
100000 loops, best of 3: 15.6 µs per loop

%timeit np.any(np.in1d(a1, a2))
10000 loops, best of 3: 27.1 µs per loop

%timeit pd.Series(a1).isin(a2).any()
10000 loops, best of 3: 135 µs per loop

使用一个包含 100k 元素的数组(没有重叠):

a3 = np.random.randint(0, 100000, 100000)
a4 = a3 + 100000

%timeit np.intersect1d(a3, a4)
100 loops, best of 3: 13.8 ms per loop    

%timeit pd.Series(a3).isin(a4).any()
100 loops, best of 3: 18.3 ms per loop

%timeit np.any(np.in1d(a3, a4))
100 loops, best of 3: 18.4 ms per loop

%timeit set(a3) & set(a4)
10 loops, best of 3: 23.6 ms per loop

%timeit any(i in a3 for i in a4)
1 loops, best of 3: 34.5 s per loop

我在评论中交换了数组。我已经纠正了它。 - Norman
@Norman 顺序重要吗?如果我们正在测试以检查它们是否共享单个值,我认为不重要。 - Alexander
哦,是的,现在已经很晚了 :-) 为了提高性能,有人可能会先放置较短的数组。 - Norman
1
np.intersect1d呢?我刚刚找到了它。 - Alex

9
您可以尝试这个。
>>> array1 = [10,5,4,13,10,1,1,22,7,3,15,9]
>>> array2 = [3,4,9,10,13,15,16,18,19,20,21,22,23]
>>> set(array1) & set(array2)
set([3, 4, 9, 10, 13, 15, 22])

如果你得到了结果,这意味着两个数组之间有共同元素。

如果结果为空,则表示没有共同元素。


3

您可以使用任何内置函数和列表推导式:

>>> array1 = [10,5,4,13,10,1,1,22,7,3,15,9]
>>> array2 = [3,4,9,10,13,15,16,18,19,20,21,22,23]
>>> any(i in array2 for i in array1)
True

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接