You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用Pandas的update函数实现DataFrame的更新/插入行操作

用DataFrame实现更新/插入(Upsert)操作:以DATE和CATEGORY为索引

问题描述

我有两个DataFrame,希望以DATE和CATEGORY列为索引,用其中一个DataFrame更新另一个。若目标DataFrame中不存在对应行则插入该行,存在则更新,但直接使用update函数仅完成了已有行的更新,无法插入新行,该如何实现需求?

示例数据

import pandas as pd

a = {'DATE': ['2022-01-01', '2022-01-02'],
     'CATEGORY': ['a', 'a'],
     'QUANTITY': [12, 14]}

b = {'DATE': ['2022-01-02', '2022-01-03', '2022-01-04'],
     'CATEGORY': ['a', 'a', 'a'],
     'QUANTITY': [0, 3, 9]}

a_df = pd.DataFrame(a)
b_df = pd.DataFrame(b)

a_df内容:

DATE CATEGORY  QUANTITY
0  2022-01-01        a        12
1  2022-01-02        a        14

b_df初始内容:

DATE CATEGORY  QUANTITY
0  2022-01-02        a         0
1  2022-01-03        a         3
2  2022-01-04        a         9

当前操作及结果

执行以下代码:

b_df.set_index(["DATE","CATEGORY"], inplace=True)
b_df.update(a_df.set_index(["DATE","CATEGORY"]))
b_df.reset_index(inplace=True)

得到的结果:

DATE CATEGORY  QUANTITY
0  2022-01-02        a      14.0
1  2022-01-03        a       3.0
2  2022-01-04        a       9.0

期望结果

希望更新后b_df包含a_df中不存在于b_df的行,即:

DATE CATEGORY  QUANTITY
0  2022-01-01        a      12.0
1  2022-01-02        a      14.0
2  2022-01-03        a       3.0
3  2022-01-04        a       9.0

解决方案

pandas的update函数仅能更新已有索引的行,无法插入新行。要实现**更新+插入(Upsert)**的效果,可使用以下两种方法:

方法1:合并后去重,保留a_df优先级

通过合并两个DataFrame,再去除重复项,确保a_df的记录优先覆盖b_df:

# 为两个DataFrame设置共同索引
a_idx = a_df.set_index(["DATE", "CATEGORY"])
b_idx = b_df.set_index(["DATE", "CATEGORY"])

# 合并DataFrame,a_df放在前面保证优先级
combined = pd.concat([a_idx, b_idx]).reset_index()

# 去重,保留第一次出现的记录(即a_df的记录优先)
result = combined.drop_duplicates(subset=["DATE", "CATEGORY"], keep="first")

# 可选:按DATE排序并重置索引
result = result.sort_values("DATE").reset_index(drop=True)

执行后result即为期望结果。

方法2:使用combine_first函数

combine_first会用调用者的数据填充被调用者的缺失值,恰好匹配需求:

# 设置共同索引
a_idx = a_df.set_index(["DATE", "CATEGORY"])
b_idx = b_df.set_index(["DATE", "CATEGORY"])

# 用a_idx更新b_idx,同时插入新行
result = b_idx.combine_first(a_idx).reset_index()

# 可选:按DATE排序并重置索引
result = result.sort_values("DATE").reset_index(drop=True)

该方法逻辑为:b_idx中已有的索引行,用a_idx的值覆盖;b_idx中没有的索引行,直接添加a_idx的对应行。


关键说明

  • update函数的局限性:仅对已有索引的行进行值更新,不会新增索引行,因此无法实现插入操作。
  • 两种方法的核心都是先对齐索引,再处理优先级,确保a_df的记录优先覆盖b_df,同时保留b_df独有的记录。

内容的提问来源于stack exchange,提问作者Ranjith

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.30 17:11:16