2017-10-21 70 views
2

鑑於兩個列表:確定數組B的各元件的位置在另一數組A

In [518]: A 
Out[518]: [3, 4, 2, 1, 7, 6, 5] 

In [519]: B 
Out[519]: [4, 6] 

B每個元素在A存在,無一例外。

我想檢索B的索引數組,如A所示。例如,4在A的索引1中存在,6在B的位置5。對於這種情況我的預期輸出是[1, 5]

這是我做得到指數:

In [520]: np.flatnonzero(np.in1d(a, b)) 
Out[520]: array([1, 5]) 

不幸的是,這不會在其他大多數情況下工作。例如,如果B = [6, 4],我的方法在輸出[5, 1]時仍輸出[1, 5]

有沒有一種有效的numpy方法來獲得我想要實現的目標?

+1

相當肯定這之前已經來呢?那些重複的東西呢? –

+0

'np.where'的幫助給出了這個確切的例子:'ix = np.in1d(A.ravel(),B).reshape(A.shape); np.where(IX)'。對不起,不符合你的第二條標準。 –

+0

@JonClements可能,找不到任何東西......至於B中的模糊,肯定任何值得它的鹽的numpy方法都應該能夠適當地處理這些,但它不會以任何方式傷害我。 –

回答

2

IIUC:

In [71]: a 
Out[71]: array([3, 4, 2, 1, 7, 6, 5, 6, 4]) 

In [72]: b 
Out[72]: array([4, 6]) 

In [73]: np.where(a==b[:,None])[1] 
Out[73]: array([1, 8, 5, 7], dtype=int64) 

In [74]: b = np.array([6, 4]) 

In [75]: np.where(a==b[:,None])[1] 
Out[75]: array([5, 7, 1, 8], dtype=int64) 

UPDATE:如果需要的第一 occurances僅索引(如果有在A陣列式兩份),然後用this solution from @Divakar,這會更快:

In [84]: (a==b[:,None]).argmax(1) 
Out[84]: array([5, 1], dtype=int64) 
+0

感謝您的回覆!我一開始尋找'[1,5]',第二個''[5,1]'。你的答案似乎到達那裏,但不是那裏:-) –

+0

@cᴏʟᴅsᴘᴇᴇᴅ,我已經改變了你的'a'陣列;-) – MaxU

+0

哦,我沒有意識到。是的,那正是我要找的!非常感謝! –

0

我不知道這是否是有效的,但

[int(np.isin(A, B[x]).nonzero()[0]) for x in range(len(B))] 

似乎符合該法案。如果唯一性不那麼保證int()部分可以被去除

+0

說實話,我自己想到了這個,但是我想要一點東西少一些... loopy。 –

0

如果m=A.sizen=B.size在哪裏方法是O(mn)。您可以通過認真梳理in1d輸出留在O((m+n)log(m+n))(在這裏唯一值):

A= np.unique(np.random.randint(0,100000,100000)) 
np.random.shuffle(A) 
B=np.unique(np.random.randint(0,10000,10000)) 
np.random.shuffle(B) 

def find(A,B): 
    pos=np.in1d(A,B).nonzero()[0] 
    return pos[A[pos].argsort()][B.argsort().argsort()] 

In [5]: np.allclose(np.where(np.equal.outer(B,A))[1],find(A,B)) 
Out[5]: True 

In [6]: %time np.where(np.equal.outer(B,A))[1] 
Wall time: 3.98 s 
Out[6]: array([88220, 13472, 12482, ..., 9795, 39524, 5727], dtype=int64) 

In [7]: %timeit find(A,B) 
22.6 ms ± 366 µs per loop (mean ± std. dev. of 7 runs, 10 loops each) 
相關問題