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

基于子串匹配的Pandas DataFrame关联实现问题

问题描述

现有两个Pandas DataFrame:

  • a 包含Name列
  • b 包含ID列

需求:找到a中Name列的值作为子串存在于b中ID列值的记录,将b关联到a上。已知b中每条记录最多匹配a中一条记录,a中记录可匹配b中多条记录。

示例数据

import pandas as pd

a = pd.DataFrame({"Name": ["Boomhaur", "Dale", "Bill", "Hank"]})
b = pd.DataFrame({"ID": ["Boomhaur-2345", "Dale-999999", "Bill-000", "Bill-001", "Peggy-420"]})

期望结果

Name             ID
0  Boomhaur  Boomhaur-2345
1      Dale    Dale-999999
2      Bill       Bill-000
2      Bill       Bill-001
3      Hank            NaN

此前在多JSON文件且ID唯一的场景下,曾用以下代码实现,但合并为单一DataFrame后ID无唯一性保障,原有逻辑不再适用,需新的解决方法:

a["_merge"] = a["Name"].apply(lambda x: x in data["ID"])
b = json.normalize(data["Data"])
b["ID"] = data["ID"]
b["_merge"] = True
a = a.join(b.set_index("_merge"), on="_merge")
解决方案

提供两种适配ID不唯一场景的高效实现方式:

方法一:通用子串匹配法

核心逻辑是为b的每条记录找到对应的Name,再与a做左连接保留所有a的记录:

# 为b添加匹配的Name列,找不到则设为None
b['matched_name'] = b['ID'].apply(
    lambda x: next((name for name in a['Name'] if name in x), None)
)

# 左连接a和b,筛选需要的列
result = a.merge(b, left_on='Name', right_on='matched_name', how='left')[['Name', 'ID']]

方法二:前缀提取法(适用于Name是ID前缀的场景)

如果Name始终是ID的前缀(如示例中用-分隔),直接提取前缀匹配效率更高:

# 从ID中提取前缀作为匹配Name
b['matched_name'] = b['ID'].str.split('-').str[0]

# 左连接得到结果
result = a.merge(b, left_on='Name', right_on='matched_name', how='left')[['Name', 'ID']]

两种方法均可得到符合预期的结果:方法一适用于Name作为任意子串存在的通用场景;方法二在Name是固定前缀的场景下性能更优。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.30 15:46:12