2014-11-14 54 views
0

我有形式Python的合併兩個陣列上特定列

a = [(12, 14, 0.3, 0.6, 0.8), (16, 18, 0.4, 0.5, 0.3), (19, 22, 0.4, 0.5, 0.3)] 
b = [(12, 14, 44, 12), (5, 4, 66, 12), (19, 22, 96, 45)] 

兩套/陣列/列表和我想找到ç這是從b找到的項目清單一個,使得只有元組中的前兩個元素需要匹配(ex1214)。因此,在這種情況下,答案Ç

c = [(12, 14, 44, 12), (19, 22, 96, 45)] 

我使用嵌套循環但它是太慢。由於

+0

在您的例子,你有一個匹配(使用'numpy'索引)'b [i,j] == a [i,]'其中'j = 0,1',這是你要求的還是它只是巧合? – gboffi 2014-11-14 13:49:10

回答

2

你可以做到這一點O(N)如果從a第一存儲所有獨特的雙項元組中的一組時間:

>>> keys = {x[:2] for x in a} 
>>> [x for x in b if x[:2] in keys] 
[(12, 14, 44, 12), (19, 22, 96, 45)] 

注如果您只是試圖匹配相同索引上的項目,則只需使用zip並提供列表理解:

>>> [y for x, y in zip(a, b) if x[:2] == y[:2]] 
[(12, 14, 44, 12), (19, 22, 96, 45)] 

#Equivalent Numpy version: 
>>> arr_a = np.array(a) 
>>> arr_b = np.array(b) 
>>> arr_b[(arr_b[:,:2] == arr_a[:,:2]).all(axis=1)] 
array([[12, 14, 44, 12], 
     [19, 22, 96, 45]]) 
+0

這是如何O(n)?在第二種情況下,按鍵操作中的'x [:2]可以在最壞的情況下使用o(n),導致整個理解爲O(m * n) – 2014-11-14 13:48:39

+0

@ '查找。 – 2014-11-14 13:49:20

+0

啊,爲好的技巧+ 1 – 2014-11-14 13:52:28

3

你可以用一個列表理解這樣做

>>> a = [(12, 14, 0.3, 0.6, 0.8), (16, 18, 0.4, 0.5, 0.3), (19, 22, 0.4, 0.5, 0.3)] 
>>> b = [(12, 14, 44, 12), (5, 4, 66, 12), (19, 22, 96, 45)] 
>>> [item for item in b for checker in a if item[:2] == checker[:2]] 
[(12, 14, 44, 12), (19, 22, 96, 45)] 
+1

編輯你的答案,因爲OP似乎想要b元素,而不是a。 – ha9u63ar 2014-11-14 13:44:38

+0

@hagubear感謝通知相同,編輯了列表理解和它的輸出:) – 2014-11-14 13:46:09

1

,你可以,如果你正在使用numpy

In [49]: a = np.array([(12, 14, 0.3, 0.6, 0.8), (16, 18, 0.4, 0.5, 0.3), (19, 22, 0.4, 0.5, 0.3)]) 

In [50]: b = np.array([(12, 14, 44.0, 12.0), (5, 4, 66.0, 12.0), (19, 22, 96.0, 45.0)]) 

In [51]: print b[np.all(a[:,:2]==b[:,:2],1)] 
[[ 12. 14. 44. 12.] 
[ 19. 22. 96. 45.]] 

它如何與numpy呢?

In [52]: print a[:,:2]==b[:,:2] 
[[ True True] 
[False False] 
[ True True]] 

np.all採用布爾的陣列,並且降低了使用沿着由可選的第二參數指定的軸線的邏輯和(或使用的所有元素)

In [53]: print np.all(a[:,:2]==b[:,:2]) 
False 

In [69]: print np.all(a[:,:2]==b[:,:2],1) 
[ True False True] 

In [70]: print np.all(a[:,:2]==b[:,:2],0) 
[False False] 

In [71]: 

在我們的情況下,當然,使用的右軸是1

(PS:我必須承認有點草率的治療類型的數組值)

+0

+1簡單快速的numpy解決方案! – 2014-11-14 14:23:45

+1

@SaulloCastro一個簡單而快速的_inscrutable_ numpy解決方案,呃! – gboffi 2014-11-14 14:27:06

0

列表綜合

 >>> a = [(12, 14, 0.3, 0.6, 0.8), (16, 18, 0.4, 0.5, 0.3), (19, 22, 0.4, 0.5, 0.3)] 
     >>> b = [(12, 14, 44, 12), (5, 4, 66, 12), (19, 22, 96, 45)] 
     >>> c=[j for i in a for j in b if i[:2]==j[:2]] 

輸出:

[(12, 14, 44, 12), (19, 22, 96, 45)]