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

Pandas按Cost_centre匹配替换Pool_costs 未匹配保留原值实现问题

问题描述

给定如下DataFrame:

输入df:

Cost_centrePool_costs
90272A
92705A
98754A
91350A

实现需求:根据Cost_centre字段值,将对应行的Pool_costs字段值替换为'B';若Cost_centre值不在指定列表中,则保留Pool_costs的原有值。本次指定需要匹配替换的Cost_centre列表为[90272, 91350]。

预期输出df:

Cost_centrePool_costs
90272B
92705A
98754A
91350B

现有尝试的问题

  • 第一种lambda+apply写法错误:else分支直接返回整个df['Pool_costs']列,没有取当前行的原值,导致结果不符合预期,错误代码如下:
df = pd.DataFrame({'Cost_centre': [90272, 92705, 98754, 91350],
                   'Pool_costs': ['A', 'A', 'A', 'A']})

pool_cc = ([90272,91350])
pool_cc_set = set(pool_cc)

df['Pool_costs'] = df['Cost_centre'].apply(lambda x: 'B' if x in pool_cc_set else df['Pool_costs'])
print (df)
  • 第二种多条件拼接写法问题:当需要匹配的Cost_centre数量较多时,需要手动拼接大量等值判断,可读性差、维护成本高,且原代码存在语法错误(括号不匹配、数值与字符串类型不匹配无法正确比较),原代码如下:
df = pd.DataFrame({'Cost_centre': [90272, 92705, 98754, 91350],
                   'Pool_costs': ['A', 'A', 'A', 'A']})

filt = df['Cost_centre'] == '90272'|df['Cost_centre'] == '91350')
df.loc[filt, 'Pool_costs'] = 'B'
推荐实现方案

优先使用pandas原生向量化操作,性能远高于apply循环,且写法简洁易维护:

方案1:isin() + loc 赋值(最推荐)

直接用isin()判断值是否在目标列表中生成过滤条件,再用loc定位赋值,无论目标列表有多少元素,只需要维护列表本身即可,代码可读性高、性能最优:

import pandas as pd

df = pd.DataFrame({'Cost_centre': [90272, 92705, 98754, 91350],
                   'Pool_costs': ['A', 'A', 'A', 'A']})

# 仅需维护这个目标匹配列表,新增/删除匹配值直接修改列表即可
pool_cc = [90272, 91350]

# 生成过滤条件:筛选Cost_centre在目标列表中的行
filt = df['Cost_centre'].isin(pool_cc)
# 仅对符合条件的行赋值为'B',不符合条件的行自动保留原值
df.loc[filt, 'Pool_costs'] = 'B'

运行结果与预期完全一致。

方案2:numpy.where() 实现

如果偏好条件判断生成整列的写法,可以用numpy.where,逻辑直观:

import pandas as pd
import numpy as np

df = pd.DataFrame({'Cost_centre': [90272, 92705, 98754, 91350],
                   'Pool_costs': ['A', 'A', 'A', 'A']})
pool_cc = [90272, 91350]

df['Pool_costs'] = np.where(
    df['Cost_centre'].isin(pool_cc), # 判断条件
    'B', # 条件成立时的取值
    df['Pool_costs'] # 条件不成立时保留原值
)

方案3:修正后的apply写法(不推荐,性能差)

如果一定要用apply实现,需要指定axis=1按行遍历,取当前行的Pool_costs值。该方式在数据量较大时性能远低于向量化操作,非必要不使用:

import pandas as pd

df = pd.DataFrame({'Cost_centre': [90272, 92705, 98754, 91350],
                   'Pool_costs': ['A', 'A', 'A', 'A']})
pool_cc = set([90272, 91350])

df['Pool_costs'] = df.apply(lambda row: 'B' if row['Cost_centre'] in pool_cc else row['Pool_costs'], axis=1)

注意:使用时需要确认Cost_centre字段的类型,如果字段是字符串类型,目标列表里的值也要对应写成字符串格式,避免类型不匹配导致匹配失败。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.03 10:57:54