【问题标题】:multiple merge operations on two dataframes using pandas使用 pandas 对两个数据帧进行多次合并操作
【发布时间】:2020-05-06 02:15:03
【问题描述】:

我有两个要实现多个操作的数据框,例如:

old_DF

id   col1   col2    col3
-------------------------
1    aaa        
2           bbb     123

new_DF

id   col1   col2    col3
-------------------------
1           xxx      999
2    xxx    kkk 

需要对这些数据帧执行以下操作:

  1. 合并两个数据框
  2. 仅将 old_DF 中的空白 (NA) 单元格替换为 new_DF 中的相应值
  3. 两个数据帧中值相互矛盾的单元格应在新数据帧中报告

期望的结果:

updated_df

id   col1   col2    col3
-------------------------
1    aaa    xxx     999
2    xxx    bbb     123

conflicts_df

id   col1   col2    col3
-------------------------
2           bbb
2           kkk     

我可以使用.append() 方法来连接两个数据框,我想可以使用.bfil().ffil() 方法来填充缺失值。但我对.bfil().ffil() 都不成功。我试过df.groupby('id').apply(lambda x: x.ffill().bfill()).drop_duplicates(),但没有得到想要的结果。此外,我不明白如何执行上述第 3 步。有没有人可以帮助解决这个问题?

【问题讨论】:

    标签: python pandas dataframe pandas-groupby


    【解决方案1】:

    设置:

    old_df = pd.DataFrame([
      [1, 'aaa', pd.NA, pd.NA],
      [2, pd.NA, 'bbb', 123]],
      columns=['id', 'col1', 'col2', 'col3'])
    new_df = pd.DataFrame([
      [1, pd.NA, 'xxx', 999],
      [2, 'xxx', 'kkk', pd.NA]],
      columns=['id', 'col1', 'col2', 'col3'])
    

    使用 combine_first 获取updated_df,设置id为索引

    old_df = old_df.set_index('id')
    new_df = new_df.set_index('id')
    updated_df = old_df.combine_first(new_df)
    
    # updated_df outputs:
    # (reset the id if necessary)
       col1 col2 col3
    id               
    1   aaa  xxx  999
    2   xxx  bbb  123
    

    使用布尔逻辑生成masks 的数据帧,检查旧帧和新帧在给定单元格中是否都有值以及值是否不同,并使用掩码从新旧帧中的任何行中选择单元格掩码为真

    mask = pd.notnull(new_df) & ~old_df.eq(new_df) & pd.notnull(old_df)
    conflicts_df = pd.concat([old_df[mask], new_df[mask]]).dropna(how='all')
    
    # conflicts_df outputs
       col1 col2 col3
    id               
    2   NaN  bbb  NaN
    2   NaN  kkk  NaN
    

    【讨论】:

    • 它对我不起作用。当我运行第一部分时,我得到类似于 old_df 的输出数据帧。在第二部分中,我用 old_df.eq(new_df) 替换了 updated_df.eq(new_df) 并且有效。但是,有两个问题:1)我必须有 id 列作为我想避免的索引,因为我可以有多个 id 列,2)数据帧必须具有相同的大小,并且在某些情况下我有可变长度的数据帧。如果我可以保持 id 列原样并将其用作“键”,那将是最好的。有没有其他方法可以将索引设置为“id”?
    • I get the output dataframe similar to old_df。在没有看到您的实际数据的情况下,我猜这是因为您的数据框中有 '' 而不是 nullscombine_first 采用第一个 non-null 值。对于其他问题,我建议使用具有代表性的数据集更新您的问题,因为您提供的样本建议使用等长的数据帧。将id 设置为索引在我看来是执行此操作的自然方式,如果将其设置为转换的索引,我不会看到任何信息丢失。你可以随时reset_index,当你需要id作为列时
    • 固定答案(将 updated_df 替换为您指出错误的 old_df)并查看有关我如何设置新旧 dfs 的更新答案。通过此设置,您还应该看到与答案中记录的相同行为
    • 此解决方案适用于所述问题。我会将我的问题修改为一个新问题以避免混淆。
    • 我已经发布了另一个问题,该问题与此问题的扩展相同。也许你也可以在那里做出贡献:stackoverflow.com/questions/61622721/…
    猜你喜欢
    • 2020-08-20
    • 2020-08-20
    • 2022-11-25
    • 2012-07-23
    • 1970-01-01
    • 2018-08-06
    • 2018-05-31
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多