2016-11-13 4 views
1

私は2つのデータフレームを持ち、どちらも重複を持つ可能性のあるキー列を持っていますが、データフレームの重複キーは大部分です。私はこれらのデータフレームをそのキーにマージしたいのですが、両方が同じ複製を持つ場合、それらの複製はそれぞれマージされます。さらに、あるデータフレームに他のキーと重複するキーがある場合は、その値をNaNとして埋めたいと思います。たとえば:鍵の重複を伴​​うpandasデータフレームのマージ

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_1、K2_2、として重複K2キーを処理したい...そしてやるだろうを取得しようとしていますデータフレームの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()コールには約1分かかります。 – dcmm88

+0

@ dcmm88私はこの特別な関数を書いた。それが状況を改善しないかどうか確認してください。 – piRSquared

+0

'' 'np.arange ... == inv'''行は、そこにnp.equalを使用することを意味していましたか?少なくとも私のために、 '=='の結果はブールです。 np.equalを使用しても、そこにメモリエラーが発生しています。データフレームが大きすぎますか? – dcmm88

関連する問題