Pandas如何用另一DataFrame替换df值并保留未匹配原有数据
问题根因
你现有代码运行后丢失数据,核心是示例代码存在笔误:两次数据集定义都赋值给了data1,第二次的更新数据集应该赋值给data2,这会导致你生成的df本身就是8行的非完整数据集,而非12行的全量旧数据。pandas的update方法本身不会删除原DataFrame的行,只会根据索引匹配,用传入DataFrame的非空值原地替换对应位置的值,只要df是完整的全量数据集,完全可以实现你的需求。
正确实现
首先先修正笔误,定义正确的两个数据集:
import pandas as pd # 全量旧值数据集 data1 = {'Region': ['Africa','Africa','Africa','Africa','Africa','Africa','Africa','Africa','Asia','Asia','Asia','Asia'], 'Country': ['South Africa','South Africa','South Africa','South Africa','South Africa','South Africa','South Africa','South Africa','Japan','Japan','Japan','Japan'], 'Product': ['ABC','ABC','ABC','ABC','XYZ','XYZ','XYZ','XYZ','DEF','DEF','DEF','DEF'], 'Year': [2016, 2017, 2018, 2019,2016, 2017, 2018, 2019,2016, 2017, 2018, 2019], 'Price': [500, 400, 0,450,750,0,0,890,500,470,0,415]} # 增量更新数据集(注意变量名为data2,不要重复赋值给data1) data2 = {'Region': ['Africa','Africa','Africa','Africa','Africa','Africa','Asia','Asia'], 'Country': ['South Africa','South Africa','South Africa','South Africa','South Africa','South Africa','Japan','Japan'], 'Product': ['ABC','ABC','ABC','ABC','XYZ','XYZ','DEF','DEF'], 'Year': [2016, 2017, 2018, 2019,2016, 2017,2016, 2017], 'Price': [200, 100, 30,750,350,120,400,370]} df = pd.DataFrame(data1) df2 = pd.DataFrame(data2)
方法1:基于update实现(和你原有逻辑一致,最简便)
将匹配列设为索引后调用update,最后重置索引即可,不会丢失任何原有行:
common_index = ['Region','Country','Product','Year'] # 设为索引 df_idx = df.set_index(common_index) df2_idx = df2.set_index(common_index) # 匹配更新 df_idx.update(df2_idx) # 重置索引将匹配列还原为普通列 df3 = df_idx.reset_index() # 如需保证Price为整数类型,追加下行代码 # df3['Price'] = df3['Price'].astype(int)
方法2:基于左连接合并实现(逻辑更透明,适合多列更新场景)
如果需要更清晰地控制更新逻辑,可以通过左连接把新旧值合并,再按规则取值:
common_index = ['Region','Country','Product','Year'] # 以全量df为基准左连接df2,分别标注新旧价格列 df_merge = df.merge(df2, on=common_index, how='left', suffixes=('_old', '_new')) # 新价格存在则取新价格,不存在则保留旧价格 df_merge['Price'] = df_merge['Price_new'].fillna(df_merge['Price_old']) # 筛选需要的列得到最终结果 df3 = df_merge[common_index + ['Price']]
结果验证
两种方法得到的df3和你预期的输出完全一致:
Region Country Product Year Price 0 Africa South Africa ABC 2016 200 1 Africa South Africa ABC 2017 100 2 Africa South Africa ABC 2018 30 3 Africa South Africa ABC 2019 750 4 Africa South Africa XYZ 2016 350 5 Africa South Africa XYZ 2017 120 6 Africa South Africa XYZ 2018 0 7 Africa South Africa XYZ 2019 890 8 Asia Japan DEF 2016 400 9 Asia Japan DEF 2017 370 10 Asia Japan DEF 2018 0 11 Asia Japan DEF 2019 415
内容的提问来源于stack exchange,提问作者A.N.
相关产品推荐
相关产品推荐

