2016-05-19 311 views
1

我有一個數據幀大熊貓:一個列表

df = pd.DataFrame({'Letters': ['A','B','C','D', 'E', 'F', 'G'], 'Numbers': [5,2,3,8,6,4,9]}) 

    Letters Numbers 
0  A  5 
1  B  2 
2  C  3 
3  D  8 
4  E  6 
5  F  4 
6  G  9 

和列表

combine = [['A', 'C'], ['E', 'F', 'G']] 

我找下面的輸出相結合列表「結合」的df,結合了數據幀的行['Letters']和df ['Numbers']的總和,使其看起來像這樣:

 Letters Numbers 
0  A,C  8 
1  B  2 
2  D  8 
3  E,F,G  19 

我一直想弄清楚使用groupby但我不認爲這是去

回答

3

的方式其實groupby會工作,如果你正確地定義組:

d = { 
    'A': ('A', 'C'), 
    'B': ('B'), 
    'C': ('A', 'C'), 
    'D': ('D'), 
    'E': ('E', 'F', 'G'), 
    'F': ('E', 'F', 'G'), 
    'G': ('E', 'F', 'G'), 
} 

df['Group'] = df.Letters.apply(lambda x: d[x]) 

請注意,你需要使用的元組(這是可哈希),而不是名單。

In [39]: df.groupby('Group').sum() 
Out[39]: 
      Numbers 
Group    
(A, C)   8 
(E, F, G)  19 
B    2 
D    8 

你當然可以用編程方式定義組,但是這會起作用。


編輯:安東Protopopov提供瞭解決方案,以生成d編程。

import itertools as it 

d = {} 
[d.update({let:tuple(comb)}) for comb in combine for let in df.Letters if let in comb] 
[d.update({let:(let)}) for let in df.Letters if let not in it.chain(*combine)] 
+1

你可以用(可能不是最好的方法)創建該字典:'d = {}; [d.update({let:comb})for comb in combine for let in df.Letters if let in comb]; [d.update({let:let})讓df.Letters如果不讓它進入.chain(* combine1)]' –

+0

謝謝,好點。讓我們看看@mohitos是否表達興趣。 – IanS

+0

謝謝各位!你的共同努力的結合讓我到了我需要的地方。 – mohitos

2

我會建議用週期,isinit.chain解決方案:

import pandas as pd 
import itertools as it 

l = [] 
for comb in combine: 
    mask = df.Letters.isin(comb) 
    l.append([comb, df.Numbers[mask].sum()]) 

whole_mask = df.Letters.isin(it.chain(*combine)) 
df_fin = pd.concat([df[~whole_mask], pd.DataFrame(l, columns=df.columns)]) 


In [40]: df_fin 
Out[40]: 
    Letters Numbers 
0   B  2 
1   D  8 
2  [A, C]  8 
3 [E, F, G]  19 

注:但我認爲與GROUPBY @IanS解決方案是更好的。

+0

你得到技術實力的積分:) – IanS

+0

@IanS謝謝,你可以添加一些代碼來創建聯合'Dict' –