2010-02-25 247 views
9

我有两个数组,a1和a2。假设len(a2) >> len(a1),并且a1是a2的子集。返回两个numpy数组之间的公共元素索引

我想快速返回a1中所有元素的a2索引。这样做的时间密集方式显然是:

from operator import indexOf 
indices = [] 
for i in a1: 
    indices.append(indexOf(a2,i)) 

这当然需要很长时间,其中a2很大。我也可以使用numpy.where()来代替(虽然a1中的每个条目在a2中只会出现一次),但我不相信它会更快。我还可以穿越大阵只有一次:

for i in xrange(len(a2)): 
    if a2[i] in a1: 
     indices.append(i) 

但我敢肯定有一个更快,更“numpy的”的方式 - 我通过numpy的方法列表看去,却什么也找不到合适的。

提前许多感谢,

d

回答

8

如何

numpy.nonzero(numpy.in1d(a2, a1))[0] 

这应该是快。从我的基本测试来看,它比您的第二代码片段len(a2) == 100,len(a1) == 10000快7倍,并且在索引45处仅有一个公共元素。这假定a1a2都没有重复元素。

+0

我比较你的解决方案戴夫柯比的上面,这对于len(a2)==约12347424,len(a1)== 1338约为1.35X更快,所以这个解决方案得到了我的投票 - 谢谢! – Dave 2010-02-25 11:57:37

+3

对于读这个的人:看起来像'setmember1d'自numpy 1.4以来已被重命名为'in1d'。 – 2012-10-16 16:26:07

+0

@AlokSinghal感谢您的支持! – 2016-06-10 18:59:45

2

怎么样:

wanted = set(a1) 
indices =[idx for (idx, value) in enumerate(a2) if value in wanted] 

这应该是O(LEN(A1)+ LEN(A2)),而不是O(LEN(A1 )* len(a2))

NB我不知道numpy,所以可能会有更''numpythonic'的方式来做到这一点,但这是我如何在纯python中做到这一点。

+0

应该枚举(a2)? – Dave 2010-02-25 11:55:51

+0

糟糕,我的坏。现在修复它。 – 2010-02-25 20:13:56

1
index = in1d(a2,a1) 
result = a2[index] 
0

numpy_indexed包(声明:我是它的作者)包含一个向量化的list.index;表现应该与目前接受的答案类似,但作为奖励,它还可以明确控制缺失值,并使用“缺失”kwarg。

import numpy_indexed as npi 
indices = npi.indices(a2, a1, missing='raise') 

此外,它也将在多维数组,即工作,找到一组在其他行的索引。

1

与@AlokSinghal非常相似,但您获得了一个已经变平的版本。

numpy.flatnonzero(numpy.in1d(a2, a1)) 
相关问题