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

如何在Pandas中筛选匹配子集DataFrame并修改指定行值?

问题解决:基于DataFrame匹配与字段更新的实现

问题场景

我们有两个Pandas DataFrame:
df1 的结构如下:

import pandas as pd

df1 = pd.DataFrame({
    "ID1": ["foo", "fizz"],
    "ID2": ["bar", "buzz"]
})

输出:

ID1   ID2
0   foo   bar
1  fizz  buzz

df2 的结构如下:

df2 = pd.DataFrame({
    "ID1": ["abc", "fizz", "fizz1", "foo", "foo"],
    "ID2": ["def", "buzz", "buzz2", "bar", "bar"],
    "Count": [7, 5, 9, 6, 6],
    "Code": ["B", "B", "C", "B", "Z"]
})

输出:

ID1    ID2  Count Code
0    abc    def      7    B
1   fizz   buzz      5    B
2  fizz1  buzz2      9    C
3    foo    bar      6    B
4    foo    bar      6    Z

需求分为两步:

  1. 从df2中筛选出ID1和ID2与df1任意行完全匹配的记录,得到子集sub_df
  2. 对sub_df执行更新:当Count字段值≥5时,将对应Code字段改为"A"
  3. 最终保留df2的原始结构,只更新符合条件的行

解决方案

这里提供两种简洁的实现方式,你可以根据自己的习惯选择:

方法一:用合并标记匹配行(直观易理解)

# 给df1加一个匹配标记列
df1['is_match'] = True

# 左连接df2和df1,标记出所有匹配的行
df2_with_match = df2.merge(df1, on=['ID1', 'ID2'], how='left')

# 复制df2得到目标结果,避免修改原数据
target_df = df2.copy()

# 同时满足两个条件:是匹配行 + Count≥5,就把Code改成"A"
update_mask = (df2_with_match['is_match'].notna()) & (target_df['Count'] >= 5)
target_df.loc[update_mask, 'Code'] = "A"

方法二:用元组匹配(更简洁)

# 把df1的ID组合转换成元组列表
id_pairs = list(df1.itertuples(index=False, name=None))

# 直接判断df2的每行ID组合是否在df1的元组列表里
match_mask = df2[['ID1', 'ID2']].apply(tuple, axis=1).isin(id_pairs)

# 复制df2并更新符合条件的行
target_df = df2.copy()
target_df.loc[match_mask & (target_df['Count'] >= 5), 'Code'] = "A"

最终结果

执行上述任意一种方法后,打印target_df就能得到需求的结果:

print(target_df)

输出:

ID1    ID2  Count Code
0    abc    def      7    B
1   fizz   buzz      5    A
2  fizz1  buzz2      9    C
3    foo    bar      6    A
4    foo    bar      6    A

小提示

  • 如果不想修改原始的df2,一定要记得用.copy()创建副本,否则会直接改动原数据
  • 第二种方法在数据量较大时,效率可能略低于第一种合并的方式,小数据量场景下完全可以放心用

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.14 07:12:34