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

如何按规则匹配子串并批量修改Pandas DataFrame列值?

问题:基于规则忽略大小写批量替换Pandas DataFrame字符串

现有数据

1. stores DataFrame

countrystore_name
FRmy new tmp
ESthis Tmp is new
FRwalmart
ESTarget
FRTMP

可复现代码:

import pandas as pd

data_stores = [['FR', 'my new tmp'], ['ES', 'this Tmp is new'], ['FR', 'walmart'], ['ES', 'Target'], ['FR', 'TMP']]
stores = pd.DataFrame(data_stores, columns=['country', 'store_name'])

2. replacements 规则DataFrame

countryoriginalreplacement
ESTMPSTORE
FRTMPSTORE
FRWALMARTIGNORE

可复现代码(修正原代码列名错误):

data_replace = [['ES', 'TMP','STORE'], ['FR', 'TMP','STORE'], ['FR', 'WALMART','IGNORE']]
replacements = pd.DataFrame(data_replace, columns=['country', 'original', 'replacement'])

需求说明

忽略大小写匹配replacements中original列的内容:

  • 若store_name完全匹配original(忽略大小写),则替换为对应的replacement
  • 若store_name包含original子串(忽略大小写),则替换该子串为replacement
  • 替换规则需按country对应匹配,最终期望结果:
countrystore_name
FRmy new STORE
ESthis STORE is new
FRIGNORE
ESTarget
FRSTORE

当前代码问题

你提供的循环代码存在以下问题:

for index, row in replacements.iterrows():
    stores['store_name'] = stores['store_name'].str.upper().replace(row["original"].upper(), row["replacement"])
  1. 大小写丢失:每次循环把整个store_name列转成大写,破坏原字符串的正确大小写(如Target变成TARGET)
  2. 规则范围错误:未按country过滤替换行,ES的规则会错误应用到FR的行(虽结果碰巧符合,但存在逻辑漏洞)
  3. 效率低下:iterrows循环在处理大DataFrame时性能极差

优化解决方案

以下方案按国家分组处理规则,区分全匹配和子串替换,同时保留原字符串的正确大小写:

import pandas as pd

# 构建每个国家的全匹配规则(忽略大小写)
full_match_map = replacements.groupby('country').apply(
    lambda x: {row['original'].upper(): row['replacement'] for _, row in x.iterrows()}
).to_dict()

# 构建每个国家的子串替换规则(忽略大小写正则)
substring_replace_map = replacements.groupby('country').apply(
    lambda x: {f'(?i){row["original"]}': row['replacement'] for _, row in x.iterrows()}
).to_dict()

def apply_replacement(row):
    country = row['country']
    text = row['store_name']
    text_upper = text.upper()
    
    # 优先处理全匹配替换
    if country in full_match_map:
        if text_upper in full_match_map[country]:
            return full_match_map[country][text_upper]
    
    # 处理子串替换
    if country in substring_replace_map:
        for pattern, repl in substring_replace_map[country].items():
            text = pd.Series([text]).str.replace(pattern, repl, regex=True).iloc[0]
    
    return text

# 应用替换规则
stores['store_name'] = stores.apply(apply_replacement, axis=1)

# 输出结果
print(stores)

执行后输出与期望结果完全一致:

country       store_name
0      FR     my new STORE
1      ES  this STORE is new
2      FR           IGNORE
3      ES           Target
4      FR           STORE

优化点说明

  • 按国家分组:确保规则仅应用到对应国家的行,避免跨区域错误替换
  • 区分全匹配/子串:优先处理全匹配场景(如walmart→IGNORE),再处理子串替换(如tmp→STORE)
  • 保留原大小写:用正则(?i)标记实现忽略大小写匹配,无需转大写破坏原字符串格式
  • 效率提升:避免iterrows循环整个DataFrame,改用分组映射和批量处理,大数据场景下性能更优

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.30 15:19:31