【问题标题】:Merging Pandas dataframes on column label and overwriting other values in matched rows在列标签上合并 Pandas 数据框并覆盖匹配行中的其他值
【发布时间】:2021-02-10 08:18:17
【问题描述】:

我有这些数据框:

rec = pd.DataFrame({'batch': ["001","002","003"], 
                    'A': [1, 2, 3], 
                    'B': [4, 5, 6]})

ing1 = pd.DataFrame({'batch': ["002","003","004"], 
                     'C': [12, 13, 14], 
                     'D': [15, 16, 17], 
                     'E': [18, 19, 10]})

ing2 = pd.DataFrame({'batch': ["001","011","012"],
                     'C': [20, 21, 22], 
                     'D': [23, 24, 25], 
                     'F': [26, 27, 28]})

我想要的是以下合并数据集,其中具有相同标签的列被后来合并的日期集覆盖,并为不存在的标签创建新列。

  batch  A  B   C   D     E     F
0   001  1  4  20  23   NaN  26.0
1   002  2  5  12  15  18.0   NaN
2   003  3  6  13  16  19.0   NaN

我尝试先将recing1 合并:

final = pd.merge(rec, ing1, how ='left', on='batch', sort=False)

中间结果:

  batch  A  B     C     D     E
0   001  1  4   NaN   NaN   NaN
1   002  2  5  12.0  15.0  18.0
2   003  3  6  13.0  16.0  19.0

然后我再次与ing2 合并,以获取C、D 和E 列中缺失的信息。

final = pd.merge(final, ing2, how ='left', on='batch', sort=False)

结果(不符合预期):

  batch  A  B   C_x   D_x     E   C_y   D_y     F
0   001  1  4   NaN   NaN   NaN  20.0  23.0  26.0
1   002  2  5  12.0  15.0  18.0   NaN   NaN   NaN
2   003  3  6  13.0  16.0  19.0   NaN   NaN   NaN

我也尝试过mergeconcatcombinefirst,但是它们似乎在将第二个表中的数据附加到主表的情况下进行操作。我能想到的唯一方法是将数据框拆分为需要从ing1 提取数据的行和需要ing2 的行,然后将它们相互附加以形成最终数据集。

【问题讨论】:

  • 您想要的结果是什么样的?是结果吗?
  • OP 想要的是第二块。我重新组织了文本,并在编辑中使其更加清晰。

标签: python pandas dataframe


【解决方案1】:

合并后直接申请np.where()怎么样?如果右列(后缀“_y”)不是 NA 则取右列,否则取左列。

final = rec.merge(ing1, how='left', on='batch')\
           .merge(ing2, how='left', on='batch')
final[["C", "D"]] = np.where(~final[["C_y", "D_y"]].isna(), final[["C_y", "D_y"]], final[["C_x", "D_x"]])

输出

print(final[["A","B","C","D","E","F"]])

   A  B     C     D     E     F
0  1  4  20.0  23.0   NaN  26.0
1  2  5  12.0  15.0  18.0   NaN
2  3  6  13.0  16.0  19.0   NaN

【讨论】:

    【解决方案2】:

    实际上,df.update() 可能是概念上最接近您所要求的功能。但是,您必须提前设置索引并预先分配输出数据帧。这可能会也可能不会比.merge() 造成更多麻烦。

    代码:

    # set index
    rec.set_index("batch", inplace=True)
    ing1.set_index("batch", inplace=True)
    ing2.set_index("batch", inplace=True)
    
    # preallocate
    final = pd.DataFrame(columns=["A","B","C","D","E","F"], index=rec.index)
    # update in order
    final.update(rec)
    final.update(ing1)
    final.update(ing2)
    

    结果:

    print(final)
    
           A  B   C   D    E    F
    batch                        
    001    1  4  20  23  NaN   26
    002    2  5  12  15   18  NaN
    003    3  6  13  16   19  NaN
    

    【讨论】:

      猜你喜欢
      • 2021-04-17
      • 1970-01-01
      • 2022-11-07
      • 1970-01-01
      • 2018-07-24
      • 2021-12-17
      • 1970-01-01
      • 2017-05-23
      • 2019-03-24
      相关资源
      最近更新 更多