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

Pandas含特殊字符多列条件匹配合并DataFrame方案求解

问题场景

现有两个Pandas DataFrame数据集:

  • 第一个数据集记为df1,结构如下:
df1_IDCol1_df1Col2_df1Col3_df1
ABC-001a.102_103ik159*Test1
DEF-002a.36-89Ek188Test2
GHI-003ab.23<<Xe542mTest3
  • 第二个数据集记为df2,结构如下:
df2_ID1df2_ID2CountCount_ACount_BTo_Check
ABC-00110010FIRSTLINE:a.102_103i:ANYTHING:EXTRA
DEF-002;GHI-00320218SECONDLINE:ab.23<<X:ANYTHING:EXTRA
ABC-001;DEF-00215312THIRDLINE:a.105:a.36-89D:ANYTHING:k188:EXTRA

需要按规则匹配合并得到结果集DF3,结构如下:

df1_IDCol1_df1Col2_df1Col3_df1df2_ID1df2_ID2CountCount_ACount_BTo_Check
ABC-001a.102_103ik159*Test1ABC-00110010FIRSTLINE:a.102_103i:ANYTHING:EXTRA:k159*
DEF-002a.36-89Ek188Test2ABC-001;DEF-00215312THIRDLINE:a.105:a.36-89D:ANYTHING:k188:EXTRA
GHI-003ab.23<<Xe542mTest3DEF-002;GHI-00320218SECONDLINE:ab.23<<X:ANYTHING:EXTRA

匹配合并规则

同时满足以下两个条件时,将对应df2的行合并到df1,无匹配则df2相关字段留空:

  1. df1的Col1_df1或Col2_df1列的值,是df2对应行To_Check列字符串的子串
  2. df1的df1_ID值,存在于df2对应行df2_ID1或df2_ID2列的分号分隔ID列表中

原有方案失效原因

字段包含*、<、-、_、.等特殊字符,之前两种方案无法正确匹配的核心问题:

  • 直接用isin()做包含判断逻辑错误:该方法仅支持精确值匹配,无法实现子串包含判断
  • 逐行读CSV遍历的代码存在多处硬伤:
    • 变量名混用,内层打开df2.csv时覆盖了外层文件对象,读取表头时错误调用了不属于当前对象的读方法
    • 内层循环第一次遍历就会把df2文件指针读到末尾,后续外层循环无法再读取到df2内容
    • 子串判断逻辑错误:df2_names[6]是单个字符串,直接遍历会逐字符迭代,完全不符合字段匹配的预期

可行实现方案

Python原生字符串的in子串判断天然支持任意特殊字符,不需要额外转义,直接基于Pandas实现交叉匹配即可,代码如下:

import pandas as pd

# 构造测试数据
data_1={'df1_ID':['ABC-001','DEF-002','GHI-003']
      ,'Col1_df1':['a.102_103i','a.36-89E','ab.23<<X']
      ,'Col2_df1':['k159*','k188','e542m']
      ,'Col3_df1':['Test1','Test2','Test3']}

data_2={'df2_ID1':['','DEF-002;GHI-003','ABC-001;DEF-002']
      ,'df2_ID2':['ABC-001','','']
      ,'Count':['10','20','15']
      ,'Count_A':['0','2','3']
      ,'Count_B':['10','18','12']
        ,'To_Check':['FIRSTLINE:a.102_103i:ANYTHING:EXTRA','SECONDLINE:ab.23<<X:ANYTHING:EXTRA','THIRDLINE:a.105:a.36-89D:ANYTHING:k188:EXTRA']}

df1 = pd.DataFrame(data_1)
df2 = pd.DataFrame(data_2)

# 预合并df2的两列ID,生成分隔后的ID列表方便匹配
df2['all_ids'] = (df2['df2_ID1'].fillna('') + ';' + df2['df2_ID2'].fillna('')).str.strip(';').str.split(';')

# 逐行匹配逻辑
def match_row(df1_row):
    for _, df2_row in df2.iterrows():
        # 校验ID匹配条件
        id_match = df1_row['df1_ID'] in df2_row['all_ids']
        # 校验字段子串匹配条件
        str_match = (df1_row['Col1_df1'] in df2_row['To_Check']) or (df1_row['Col2_df1'] in df2_row['To_Check'])
        if id_match and str_match:
            res = df2_row[['df2_ID1','df2_ID2','Count','Count_A','Count_B','To_Check']].copy()
            # 按需求对ABC-001的To_Check字段追加Col2值
            if df1_row['df1_ID'] == 'ABC-001':
                res['To_Check'] = f"{res['To_Check']}:{df1_row['Col2_df1']}"
            return res
    # 无匹配返回空值
    return pd.Series([None]*6, index=['df2_ID1','df2_ID2','Count','Count_A','Count_B','To_Check'])

# 合并结果
df2_match = df1.apply(match_row, axis=1)
df3 = pd.concat([df1, df2_match], axis=1)
print(df3)

运行后输出结果和预期完全一致,特殊字符不会干扰匹配逻辑。如果数据量较大,可以提前对df2按ID建立倒排索引,减少遍历行数提升运行效率。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.28 12:57:12