如何基于模糊匹配的多值分隔符键连接两个DataFrame

10次阅读

如何基于模糊匹配的多值分隔符键连接两个DataFrame

本文介绍在pandas中实现“一对多”式条件连接的方法:当df2的dest列以斜杠分隔多个值(如”a/b/c”)时,将df1中(org, dest)与df2中org相同且dest为该字符串中任一子项的记录进行左连接。

在实际数据处理中,常遇到连接键不完全一致但存在逻辑包含关系的情况——例如,df2中的 dest 字段存储的是用 / 分隔的多个目标值(如 “A/B/C”),而 df1 中的 dest 是单一值(如 “B”)。此时标准的 merge 无法直接匹配,需先对 df2 的 dest 列进行结构化解析,再执行常规连接。

核心思路是:

  1. 将 df2[‘dest’] 按 ‘/’ 拆分为列表;
  2. 使用 .explode() 将每个列表展开为多行(一行变多行),使复合键扁平化;
  3. 基于标准化后的 (org, dest) 对两表执行 left merge。

✅ 完整实现代码如下:

import pandas as pd  # 构造示例数据 df1 = pd.DataFrame({     'Name': ['Ashok', 'Rahul', 'Anupa', 'Sam'],     'org':  ['A',     'A',     'B',     'A'],     'dest': ['B',     'C',     'A',     'B'] })  df2 = pd.DataFrame({     'org':   ['A', 'B', 'A'],     'dest':  ['A/B/C', 'C', 'W'],     'Amount': [10, 20, 30] })  # 关键步骤:拆分 + 展开 + 连接 df2_exploded = df2.assign(dest=df2['dest'].str.split('/')).explode('dest') df3 = df1.merge(df2_exploded, on=['org', 'dest'], how='left')  print(df3)

输出结果:

Name org dest  Amount 0  Ashok   A    B    10.0 1  Rahul   A    C    10.0 2  Anupa   B    A     NaN 3    Sam   A    B    10.0

⚠️ 注意事项:

  • str.split(‘/’) 默认返回 list,若某 dest 值不含 /(如 “C” 或 “W”),会生成单元素列表([‘C’]),explode 仍能正确处理;
  • 若 dest 含空值(NaN),str.split() 会返回 NaN,explode 会保留该行但 dest 为 NaN,可能导致连接失败,建议提前用 df2 = df2.dropna(subset=[‘dest’]) 清洗;
  • 若需严格匹配原始预期输出中 “Rahul” 行 Amount 为空(即不填充 10),说明业务逻辑要求仅匹配 df2 中 org 和 dest 同时精确对应的记录(如 “A” → “A/B/C” 仅当 dest=’A’ 才匹配),本方案已满足;但注意 “Rahul” 实际应匹配到 df2 第一行(org=’A’, dest=’A/B/C’ → 展开后含 ‘C’),因此 Amount=10 是正确的——若业务要求不同,请进一步明确匹配优先级(如正则、前缀匹配等)。

该方法简洁高效,适用于中等规模数据;对于超大规模数据,可考虑使用 pd.concat + map 或预构建映射字典优化性能。

text=ZqhQzanResources