【问题标题】:Merge Pandas Dataframe: how to add columns and replace values合并 Pandas Dataframe:如何添加列和替换值
【发布时间】:2020-10-02 22:58:08
【问题描述】:

我有一个数据框 df1 并想合并其他(许多)数据框 df2 以便:

  • 合并发生在匹配的(多)索引上
  • 如果缺少,则会创建新列
  • 如果列已存在,则替换值

什么是正确的 pandas 操作以及使用什么参数?我查看了 concat/join/merge/assign/append 但还没有找到。

数据框代码:

df1 = pd.DataFrame({'A':['A1', 'A2', 'A3', 'A4'],
                    'B':['B1', 'B2' ,'B3', 'B4'],
                    'C':['C1' ,'C2', 'C3', 'C4']},
                  index = [1,2,3,4])

df2 = pd.DataFrame({'C':['NewC'], 'D':['NewD']},
                  index=[3])

【问题讨论】:

    标签: pandas join merge concat


    【解决方案1】:

    一种方法是使用combine_first:

    df2.combine_first(df1)
    

    输出:

        A   B     C     D
    1  A1  B1    C1   NaN
    2  A2  B2    C2   NaN
    3  A3  B3  NewC  NewD
    4  A4  B4    C4   NaN
    

    另一种方法是使用joinfillna

    df1[['A','B']].join(df2).fillna(df1)
    

    输出:

        A   B     C     D
    1  A1  B1    C1   NaN
    2  A2  B2    C2   NaN
    3  A3  B3  NewC  NewD
    4  A4  B4    C4   NaN
    

    第三种方式,

    df1a = df1.reindex(df1.columns.union(df2.columns), axis=1)
    df1a.update(df2)
    df1a
    

    时间:

    %%timeit pd.concat((df1,df2),sort=False).groupby(level=0).last()  
    

    每个循环 4.56 ms ± 947 µs(平均值 ± 标准偏差,7 次运行,每次 100 个循环)

    %%timeit 
    df1a = df1.reindex(df1.columns.union(df2.columns), axis=1)  
    df1a.update(df2)
    df1a
    

    每个循环 2.93 ms ± 133 µs(平均值 ± 标准偏差,7 次运行,每次 100 个循环)

    %timeit df1[['A','B']].join(df2).fillna(df1)
    

    每个循环 5.2 ms ± 89.7 µs(7 次运行的平均值 ± 标准偏差,每次 100 个循环)

    %timeit df2.combine_first(df1)
    

    每个循环 5.37 ms ± 127 µs(平均值 ± 标准偏差,7 次运行,每次 100 个循环)

    【讨论】:

    • combine_first 是一个很好的答案 Scott,我没有意识到索引上的传统 pd.merge 不能解决这里的问题。部分原因是因为我无法测试,因为 OP 发布了图像而不是将值粘贴到...感谢您编辑帖子。
    • 我刚刚测试过,combine_first 似乎很慢,因为我递归使用它(如 for row in df.itertuples(index=True): # ...request values from DB based on row and process them into newDF df =newDF.combine_first(df) )会尝试加入。 (将来也会发布代码示例)
    • 是的,抱歉,显然是我自己的请求需要时间,而不是 combine_first...
    【解决方案2】:

    首先组合是正确的方法,另一种选择是连接并从组level=0(索引)中获取最后一个:

    pd.concat((df1,df2),sort=False).groupby(level=0).last()
    

    df.assign

    df1.assign(**df2).fillna(df1)
    

        A   B     C     D
    1  A1  B1    C1   NaN
    2  A2  B2    C2   NaN
    3  A3  B3  NewC  NewD
    4  A4  B4    C4   NaN
    

    【讨论】:

      猜你喜欢
      • 2018-09-07
      • 2014-06-12
      • 2019-08-15
      • 1970-01-01
      • 2022-09-30
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多