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

Python Pandas子串匹配异常问题排查与修正

基于SKU精确匹配优先的DataFrame合并问题解决

问题背景

我有两个DataFrame(DFA和DFB),需要基于SKU列的精确匹配优先、无精确匹配时启用子串匹配的规则,将DFA中的Company列合并到DFB中。

现有实现代码

# 移除空格、特殊字符并转换数据类型为字符串
dfa['Clean SKU'] = dfa['SKU'].replace(r'[^0-9a-zA-Z ]', '', regex=True).replace("'", '')
dfb['Clean SKU'] = dfb['SKU'].replace(r'[^0-9a-zA-Z ]', '', regex=True).replace("'", '')

dfa['Clean SKU'] = dfa['Clean SKU'].replace(r'\s+', '', regex=True)
dfb['Clean SKU'] = dfb['Clean SKU'].replace(r'\s+', '', regex=True)

# 转换数据类型
dfa['Clean SKU'] = dfa['Clean SKU'].astype(str)
dfb['Clean SKU'] = dfb['Clean SKU'].astype(str)

# 创建用于合并的列并转换为小写
dfa['SKU_to_merge'] = dfa['Clean SKU'].str.lower()

# 从Clean SKU列提取唯一列表生成匹配正则
pat = r'(%s)'%'|'.join(dfa['Clean SKU'].str.lower().unique())

# 创建匹配列
dfb['SKU_to_merge'] = dfb['Clean SKU'].str.lower().str.extract(pat)

# 基于匹配列合并DataFrame
dfb = dfb.merge(dfa[['SKU_to_merge','Company']], on='SKU_to_merge', how='left')

问题异常描述

对于SKU为601251x的记录,该SKU在DFA中存在,理应精确匹配601251x并关联Google公司,但实际错误匹配了Amazon。核心需求是:仅当无精确匹配时才启用子串匹配,需要修正该异常。

修正方案

问题出在原正则匹配未优先处理精确匹配,且未按SKU长度排序导致短SKU误匹配长SKU。解决思路是先执行精确匹配,对未匹配记录再按规则做子串匹配:

# 1. 统一清洗SKU(合并重复逻辑,转小写)
dfa['Clean SKU'] = dfa['SKU'].replace(r'[^0-9a-zA-Z ]', '', regex=True)\
                            .replace("'", '').replace(r'\s+', '', regex=True)\
                            .astype(str).str.lower()
dfb['Clean SKU'] = dfb['SKU'].replace(r'[^0-9a-zA-Z ]', '', regex=True)\
                            .replace("'", '').replace(r'\s+', '', regex=True)\
                            .astype(str).str.lower()

# 2. 先执行精确匹配
dfb = dfb.merge(dfa[['Clean SKU', 'Company']], 
                left_on='Clean SKU', right_on='Clean SKU', 
                how='left', suffixes=('', '_exact'))

# 3. 处理未精确匹配的记录,执行子串匹配
unmatched = dfb[dfb['Company'].isna()]
if not unmatched.empty:
    # 按SKU长度倒序生成正则,优先匹配更长的SKU,避免短SKU误匹配
    sorted_sku_list = sorted(dfa['Clean SKU'].unique(), key=len, reverse=True)
    match_pattern = r'(' + '|'.join(sorted_sku_list) + ')'
    
    unmatched['matched_sku'] = unmatched['Clean SKU'].str.extract(match_pattern, expand=False)
    # 合并子串匹配的Company数据
    unmatched = unmatched.merge(dfa[['Clean SKU', 'Company']], 
                                left_on='matched_sku', right_on='Clean SKU', 
                                how='left', suffixes=('', '_sub'))
    # 用子串匹配结果填补空值
    unmatched['Company'] = unmatched['Company_sub'].fillna(unmatched['Company'])
    
    # 将修正结果回填到原DFB
    dfb.loc[dfb['Company'].isna(), 'Company'] = unmatched['Company']

# 清理临时辅助列
dfb = dfb.drop(columns=['Company_exact', 'matched_sku', 'Company_sub', 'Clean SKU_y'], errors='ignore')

修正说明

  • 先做精确匹配,确保存在完全一致的SKU能直接关联正确的Company;
  • 子串匹配前按SKU长度倒序生成正则,优先匹配更长的SKU,避免短SKU(如60125)误匹配包含它的长SKU(如601251x);
  • 仅对未精确匹配的记录执行子串匹配,严格遵循需求规则。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.19 20:15:34