2016-11-13 40 views
1

我有2個數據幀,都有一個可能有重複的關鍵列,但數據幀大多有相同的重複密鑰。我想合併這些關鍵字上的數據框,但是這樣當兩個重複項相同時,這些重複項分別被合併。另外,如果一個數據框比另一個有更多的重複鍵,我希望它的值被填充爲NaN。例如:合併熊貓數據幀與密鑰重複

df1 = pd.DataFrame({'key': ['K0', 'K1', 'K2', 'K2', 'K2', 'K3'], 
        'A': ['A0', 'A1', 'A2', 'A3', 'A4', 'A5']}, 
        columns=['key', 'A']) 
df2 = pd.DataFrame({'B': ['B0', 'B1', 'B2', 'B3', 'B4', 'B5', 'B6'], 
        'key': ['K0', 'K1', 'K2', 'K2', 'K3', 'K3', 'K4']}, 
        columns=['key', 'B']) 

    key A 
0 K0 A0 
1 K1 A1 
2 K2 A2 
3 K2 A3 
4 K2 A4 
5 K3 A5 

    key B 
0 K0 B0 
1 K1 B1 
2 K2 B2 
3 K2 B3 
4 K3 B4 
5 K3 B5 
6 K4 B6 

我試圖讓下面的輸出

key A B 
0 K0 A0 B0 
1 K1 A1 B1 
2 K2 A2 B2 
3 K2 A3 B3 
6 K2 A4 NaN 
8 K3 A5 B4 
9 K3 NaN B5 
10 K4 NaN B6 

所以基本上,我想對待複製K2鍵作爲K2_1,K2_2,......然後做how ='outer'在數據框上合併。 任何想法我可以做到這一點?

回答

3

再快

%%cython 
# using cython in jupyter notebook 
# in another cell run `%load_ext Cython` 
from collections import defaultdict 
import numpy as np 

def cg(x): 
    cnt = defaultdict(lambda: 0) 

    for j in x.tolist(): 
     cnt[j] += 1 
     yield cnt[j] 


def fastcount(x): 
    return [i for i in cg(x)] 

df1['cc'] = fastcount(df1.key.values) 
df2['cc'] = fastcount(df2.key.values) 

df1.merge(df2, how='outer').drop('cc', 1) 

更快的答案;不能擴展

def fastcount(x): 
    unq, inv = np.unique(x, return_inverse=1) 
    m = np.arange(len(unq))[:, None] == inv 
    return (m.cumsum(1) * m).sum(0) 

df1['cc'] = fastcount(df1.key.values) 
df2['cc'] = fastcount(df2.key.values) 

df1.merge(df2, how='outer').drop('cc', 1) 

老答案

df1['cc'] = df1.groupby('key').cumcount() 
df2['cc'] = df2.groupby('key').cumcount() 

df1.merge(df2, how='outer').drop('cc', 1) 

enter image description here

+0

有沒有辦法對任何更快做到這一點?我正在處理大約4M條目的數據框,雖然合併基本上是瞬時的,但cumcount()調用大約需要一分鐘。 – dcmm88

+0

@ dcmm88我寫了這個特別的功能。檢查它是否改善情況。 – piRSquared

+0

'''np.arange ... == inv'''行,你打算使用np.equal嗎?因爲至少對我來說'=='的結果是一個布爾值。即使當我使用np.equal時,我在那裏出現內存錯誤,也許我的數據幀太大了? – dcmm88