【问题标题】:merge pandas dataframe with key duplicates将 pandas 数据框与关键重复项合并
【发布时间】:2017-03-27 07:23:06
【问题描述】:

我有 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' 合并。 有什么想法可以做到这一点吗?

【问题讨论】:

    标签: python pandas dataframe merge


    【解决方案1】:

    又快了

    %%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)
    

    【讨论】:

    • 有没有办法更快地做到这一点?我正在使用大约 4M 条目的数据框,虽然合并基本上是瞬时的,但 cumcount() 调用大约需要一分钟。
    • @dcmm88 这个函数我写得很特别。检查它是否没有改善这种情况。
    • np.arange... == inv 行,你的意思是在那里使用 np.equal 对吗?因为至少对我来说'=='的结果是一个布尔值。即使当我使用 np.equal 时,也会出现内存错误,可能是我的数据框太大了?
    • @dcmm88 是的。这不好。不缩放。还在做某事
    • @dcmm88 我提高了性能,但需要 cython。如果你使用的是 jupyter notebook,你应该没问题。
    【解决方案2】:
    df1.set_index('key', inplace=True)
    
    df2.set_index('key', inplace=True)
    
    merged_df = pd.merge(df1, df2, left_index = True, right_index = True, how= 'inner')
    merged_df.reset_index('key', drop=False, inplace=True)
    

    【讨论】:

    • 如果您能解释您添加的关键字而不是仅提供代码答案,通常会更有帮助。
    猜你喜欢
    • 2021-12-14
    • 1970-01-01
    • 2018-12-27
    • 2021-10-08
    • 1970-01-01
    • 2018-11-01
    • 1970-01-01
    • 1970-01-01
    • 2019-11-22
    相关资源
    最近更新 更多