如何用不同大小的新DataFrame通过多列匹配更新旧DataFrame的值?
Pandas高效更新不同行数DataFrame的方案
你遇到的问题是要通过Primary_ID和Secondary_ID这两个主键列匹配,用新DataFrame的Value更新旧DataFrame对应行的值,直接用update会因为索引不匹配失败,逐行循环又效率太低。这里给你两个高效的矢量化解决方案:
方法一:设置复合索引后使用update
这是最简洁高效的方式,利用pandas的索引匹配机制完成更新:
import pandas as pd # 先定义示例中的ID变量 ID1, ID2, ID3 = "A", "B", "C" old_df = pd.DataFrame({ "Primary_ID":[ID1,ID1,ID1,ID2,ID2,ID2,ID3,ID3], "Secondary_ID":[1,2,3,4,5,6,7,8], "Value":[100,200,300,400,5000,600,700,8000] }) new_df = pd.DataFrame({ "Primary_ID":[ID3,ID2], "Secondary_ID":[8,5], "Value":[800,500] }) # 将两个DataFrame的主键列设为复合索引 old_df_idx = old_df.set_index(["Primary_ID", "Secondary_ID"]) new_df_idx = new_df.set_index(["Primary_ID", "Secondary_ID"]) # 调用update,仅更新索引匹配的行 old_df_idx.update(new_df_idx) # 恢复原索引结构 updated_df = old_df_idx.reset_index() print(updated_df)
运行后,old_df中(ID2,5)的Value会从5000改成500,(ID3,8)的Value从8000改成800,其他行保持不变。
方法二:Merge+填充更新
如果不想修改原DataFrame的索引,可以用merge配合fillna实现更新,同样是矢量化操作,效率远高于循环:
# 用merge关联新旧数据,保留原表所有行 merged_df = old_df.merge( new_df, on=["Primary_ID", "Secondary_ID"], how="left", suffixes=("", "_new") # 区分新旧Value列 ) # 用新值填充匹配到的行,未匹配的保留原值 merged_df["Value"] = merged_df["Value_new"].fillna(merged_df["Value"]) # 移除临时列 updated_df = merged_df.drop(columns=["Value_new"]) print(updated_df)
方案对比
- 方法一代码更简洁,执行效率最高,适合大多数场景;
- 方法二无需修改索引,逻辑更直观,适合对索引有保留需求的场景。
两种方案都是pandas原生的矢量化操作,避免了逐行循环的性能瓶颈,数据量越大优势越明显。
内容的提问来源于stack exchange,提问作者Chronicles
相关产品推荐
相关产品推荐

