如何合并两个pandas DataFrame匹配索引并实现数据覆盖更新
解决方案
你遇到的问题本质是选错了方法,merge是用于按列值关联两个表做拼接的场景,不适合同索引位置的覆盖更新需求,pandas有内置的专门方法可以直接实现你的需求:DataFrame.update()。
方法说明
DataFrame.update()的特性完全匹配你的需求:
- 按索引、列名自动匹配两个表的对应位置
- 优先用更新表(你的
geoid)的数值覆盖原表(你的original)的同位置内容,空值、旧值都会被替换 - 保留原表的全部行,更新表没有的行不会做任何修改
示例代码
import pandas as pd # 你的示例数据 geoid = pd.DataFrame({'Address': ['4050 Blake Ct', '1234 w east st'], 'ID': ['789456', '654321'], 'State': ['NV', 'NV'], 'Zip': ['88991', '88991'], 'Ph': ['789456', '456132']}) original = pd.DataFrame({'Address': ['', '1234 w east st', 'PO box 789'], 'ID': ['789456', '654321', '654789'], 'State': ['NV', 'CA', 'CA'], 'Zip': ['88991', '88991', '99663'], 'Ph': ['789456', '456132', '741852']}) # 先复制原表避免修改原始数据 result = original.copy() # 执行更新,overwrite=True表示无论原表值是什么都覆盖,默认就是True可以省略 result.update(geoid, overwrite=True) print(result)
执行后输出就是你预期的结果:
Address ID State Zip Ph 0 4050 Blake Ct 789456 NV 88991 789456 1 1234 w east st 654321 NV 88991 456132 2 PO box 789 654789 CA 99663 741852
补充说明
为什么之前用merge不行
merge的逻辑是按你指定的on参数的列值匹配行,你把所有列都设为关联键的情况下,只要两个表对应逻辑行有任意一列值不同(比如示例中original索引0的Address是空值,geoid索引0的Address有值),就会被判定为不匹配的行,自然得不到更新效果。
按主键匹配的扩展写法
如果后续遇到两个表索引不对应,需要按唯一主键(比如ID列)匹配更新的场景,可以先把两个表的主键设为索引再调用update即可:
result = original.set_index('ID') geoid = geoid.set_index('ID') result.update(geoid) result = result.reset_index()
内容的提问来源于stack exchange,提问作者spareTimeCoder
相关产品推荐
相关产品推荐

