如何利用另一个pandas DataFrame更新目标DataFrame的对应值?
解决方案:用Pandas实现DataFrame的更新与保留
我来帮你解决这个问题!你想要的效果是用df2的数据覆盖df1中匹配行的B值,同时保留df1里df2没有的行,这其实是很常见的"更新+保留"场景,之前用pd.update或pd.merge没成功大概率是没处理好匹配逻辑,下面给你几个靠谱的实现方法:
先构造测试数据
首先先把你给出的两个DataFrame用代码还原,方便后续测试:
import pandas as pd df1 = pd.DataFrame({'A': ['foo', 'bar', 'baz'], 'B': [2, 3, 4]}) df2 = pd.DataFrame({'A': ['foo', 'bar'], 'B': [40, 50]})
方法1:使用combine_first(最简洁)
这个方法会自动用df2的非缺失值覆盖df1的对应位置,同时保留df1独有的行,只需要先把匹配列(A列)设为索引对齐:
# 将A列设为索引,对齐后合并 df_result = df2.set_index('A').combine_first(df1.set_index('A')).reset_index() # 把索引列改回原列名A df_result = df_result.rename(columns={'index': 'A'})
运行后得到的df_result就是你想要的结果:
| A | B |
|---|---|
| foo | 40 |
| bar | 50 |
| baz | 4 |
方法2:使用pd.update(需要索引匹配)
update本身是按索引匹配更新的,如果你之前直接用df1.update(df2)会按行位置匹配而不是A列的值,所以需要先把A列设为索引:
# 先把两个DataFrame的A列设为索引 df1.set_index('A', inplace=True) df2.set_index('A', inplace=True) # 用df2更新df1(inplace操作,直接修改df1) df1.update(df2) # 恢复索引为普通列 df_result = df1.reset_index()
这个方法会直接修改df1,如果你不想改动原数据,可以先复制df1再操作:df_copy = df1.copy(),再对copy进行处理。
方法3:使用pd.merge+fillna(适合复杂场景)
如果你的DataFrame有更多列需要处理,merge的方式更灵活,通过左连接保留df1的所有行,再用df2的值填充缺失:
# 左连接保留df1的所有行,给两列B加后缀区分 df_merge = pd.merge(df1, df2, on='A', how='left', suffixes=('_df1', '_df2')) # 优先用df2的B值,没有的话用df1的B值 df_merge['B'] = df_merge['B_df2'].fillna(df_merge['B_df1']) # 只保留需要的A和B列 df_result = df_merge[['A', 'B']]
为什么之前的尝试可能失败?
- 用
pd.update时没设置索引:默认是按行的位置匹配,而不是按A列的值匹配,所以会更新错行 - 用
pd.merge时用了默认的inner连接:会丢失df1中df2没有的行(比如baz),如果用outer连接会产生重复的B列,需要额外处理
内容的提问来源于stack exchange,提问作者Schiphol
相关产品推荐
相关产品推荐

