如何对比两个Pandas DataFrame指定列,实现更新或追加数据
解决Pandas DataFrame匹配更新与追加问题
问题描述
我有两个Pandas DataFrame,想要对比二者的['Pyramid Key','FCST_YR_PRD']列:
- 若这两列的值完全相等,则更新另一列(比如
DMD_ACTL_QTY)的内容; - 若不相等,则将新数据追加到原DataFrame中(比如用concat方法)。
我尝试了以下代码,但没达到预期:
if demand_history[['Pyramid Key','FCST_YR_PRD']] == azlog_3[['Pyramid Key','FCST_YR_PRD']]: demand_history['DMD_ACTL_QTY'] == azlog_3['DMD_ACTL_QTY']
解决方案
直接用逐行判断的if语句在Pandas里行不通,因为DataFrame的比较会返回布尔值矩阵,无法直接作为if的判断条件。推荐用以下两种方法实现需求:
方法一:使用merge+combine_first(推荐)
先通过两列主键合并两个DataFrame,然后用新数据覆盖旧数据,再补充原数据中没有的行:
import pandas as pd # 设置主键列 key_cols = ['Pyramid Key', 'FCST_YR_PRD'] # 合并两个DataFrame,保留azlog_3的更新值 merged = demand_history.merge(azlog_3, on=key_cols, how='outer', suffixes=('_old', '_new')) # 更新DMD_ACTL_QTY:优先用azlog_3的值,没有则保留原数据 merged['DMD_ACTL_QTY'] = merged['DMD_ACTL_QTY_new'].combine_first(merged['DMD_ACTL_QTY_old']) # 整理最终结果,保留需要的列 demand_history_updated = merged[key_cols + ['DMD_ACTL_QTY']]
方法二:先更新匹配行,再追加不匹配行
- 找出两个DataFrame中主键匹配的行,更新
DMD_ACTL_QTY - 找出azlog_3中主键不在demand_history里的行,追加到结果中
import pandas as pd key_cols = ['Pyramid Key', 'FCST_YR_PRD'] # 先复制原DataFrame避免修改原数据 demand_history_updated = demand_history.copy() # 用merge找出匹配的行,更新DMD_ACTL_QTY matched = demand_history_updated.merge(azlog_3, on=key_cols, how='inner') demand_history_updated.loc[demand_history_updated.set_index(key_cols).index.isin(matched.set_index(key_cols).index), 'DMD_ACTL_QTY'] = matched['DMD_ACTL_QTY_y'].values # 找出azlog_3中不在原数据里的行,追加进去 new_rows = azlog_3[~azlog_3.set_index(key_cols).index.isin(demand_history.set_index(key_cols).index)] demand_history_updated = pd.concat([demand_history_updated, new_rows], ignore_index=True)
原代码问题说明
- 直接用
DataFrame == DataFrame会返回一个布尔值的DataFrame,不能作为if的判断条件,因为if需要单个布尔值; - 赋值用的是
==(比较运算符),而不是=(赋值运算符),这会导致没有实际修改数据。
内容的提问来源于stack exchange,提问作者vanetoj
相关产品推荐
相关产品推荐

