2014-03-05 57 views
1

我有兩個NumPy數組。例如:NumPy數組相交的指數

arr1 = np.array(['a','b','a','c','c','b','a','d']) 
arr2 = np.array(['a','b','c','d']) 

我的任務是創造arr2數組,其中arr1 == arr2的索引列表。

所需列表的長度應該等於len(arr1)。例如,在我的情況下,正確的答案是[0,1,0,2,2,1,0,3]

這樣做的簡短方法是什麼?這裏可以使用列表理解嗎?

回答

3

不知道numpy有這樣的方法,但這裏是一個內置的方式,這需要O(N)時間:

In [9]: lookup = {v:i for i, v in enumerate(arr2)} 

In [10]: [lookup[v] for v in arr1] 
Out[10]: [0, 1, 0, 2, 2, 1, 0, 3] 
3

可以使用廣播與NumPy的像這樣做,但是如果你的陣列是大你可以最終分配大量內存的中間結果

>>> import numpy as np 
>>> arr1, arr2 = np.array(['a','b','a','c','c','b','a','d']), np.array(['a','b','c','d']) 
>>> arr1 == arr2[:, None] 
array([[ True, False, True, False, False, False, True, False], 
     [False, True, False, False, False, True, False, False], 
     [False, False, False, True, True, False, False, False], 
     [False, False, False, False, False, False, False, True]], dtype=bool) 
>>> (arr1 == arr2[:, None]).argmax(axis=0) 
array([0, 1, 0, 2, 2, 1, 0, 3]) 
>>> 

否則留意arraysetops萬一有人增加了一個return_index參數intersect1d

+0

+1,輝煌的解決方案;) – zhangxaochen

+0

不僅如此;應該比另一個更快,對於更大的數據集。 –

+0

使用'arr2 [:, np.newaxis]'可能會更清楚地知道索引操作的功能。 – JAB

4

我注意到,arr2是排序的,是由設計?如果是這樣,你可以這樣做:

arr1 = np.array(['a','b','a','c','c','b','a','d']) 
arr2 = np.array(['a','b','c','d']) 

arr2.searchsorted(arr1) 
# array([0, 1, 0, 2, 2, 1, 0, 3]) 

正如@JAB提到你可以使用分揀機關鍵字searchsorted時ARR2未排序:

arr2 = np.array(['d', 'c', 'b', 'a']) 
sorter = arr2.argsort() 
sorter[arr2.searchsorted(arr1, sorter=sorter)] 
# array([3, 2, 3, 1, 1, 2, 3, 0]) 

,這是O(N *日誌(N) )方法,因爲argsort,但它應該仍然是非常快的許多用例。

+0

即使沒有對arr2進行排序,也可以執行arr2.searchsorted(arr1,sorter = arr2.argsort())來實現相同的效果,而不實際對arr2進行排序。無論哪種方式,這可能比E先生的答案更有記憶效率,儘管我沒有做過時間比較,看哪個花費更長的時間。 – JAB

+0

是的,我認爲這是最好的答案,如果ARR2排序 – YXD

+0

@JAB,好的一點,但請記住,如果你打算使用分揀機,你需要使用'sorter [a.searchsorted(key,sorter = sorter )]'來獲得原始數組中的索引。 –