如何用Pandas从DataFrame字符串列提取带clinic/hospital后缀的名称?
解决方案
首先明确核心匹配规则:要提取的名称必须紧跟在空格之后、clinic/hospital之前,且名称来自df1的Name列。你用apply后全为None,大概率是匹配逻辑的正则写法、匹配顺序或大小写处理出了问题,下面给出两种可行方案:
方案1:用pandas内置的str.extract(推荐,更高效)
这种方法无需自定义apply函数,直接利用正则批量提取,代码更简洁且性能更好。
步骤1:准备示例数据(可替换为你的真实数据)
import pandas as pd import re df1 = pd.DataFrame({'Name': ['Green Valley', 'Sunny Side', 'Maple']}) df2 = pd.DataFrame({'Description': [ 'Visited Green Valley clinic yesterday', 'Sunny Side hospital is nearby', 'Maple store is closed', 'Clinic of Green Valley is great' ]})
步骤2:构建正则匹配规则
- 先把df1的名称按长度倒序排序:避免短名称先匹配(比如如果有"Maple"和"Maple Creek",长名称优先匹配才不会被截断)
- 转义名称中的特殊字符:防止名称里的
.、*等字符被正则解析为语法符号 - 正则逻辑:捕获名称,后面必须跟空格+
clinic/hospital,同时开启不区分大小写匹配
# 整理名称列表并按长度倒序 name_list = df1['Name'].tolist() name_list.sort(key=len, reverse=True) # 构建正则模式 name_pattern = '|'.join([re.escape(name) for name in name_list]) # 编译正则,开启不区分大小写 regex = re.compile(fr'({name_pattern})\s+(?:clinic|hospital)', re.IGNORECASE)
步骤3:提取匹配结果
df2['Extracted Name'] = df2['Description'].str.extract(regex)
运行后结果:
| Description | Extracted Name |
|---|---|
| Visited Green Valley clinic yesterday | Green Valley |
| Sunny Side hospital is nearby | Sunny Side |
| Maple store is closed | NaN |
| Clinic of Green Valley is great | NaN |
方案2:修复自定义apply函数
如果你坚持要用apply,需要修正函数内的匹配逻辑:
def extract_target_name(text): # 遍历排序后的名称列表 for name in name_list: # 匹配规则:名称 + 空格 + clinic/hospital,不区分大小写 match = re.search(fr'{re.escape(name)}\s+(?:clinic|hospital)', text, re.IGNORECASE) if match: return name return None df2['Extracted Name'] = df2['Description'].apply(extract_target_name)
常见问题排查(为什么之前全是None)
- 没处理空格:比如直接写
name + 'clinic',但实际文本中名称和后缀之间有空格,导致匹配失败 - 忽略大小写:文本中出现
Clinic/Hospital大写形式,正则没开启re.IGNORECASE导致不匹配 - 未转义特殊字符:如果名称里有
St. Mary这类带.的字符串,.会被正则解析为任意字符,导致匹配错误 - 匹配顺序错误:短名称先匹配,长名称被截断(比如先匹配"Maple",就不会匹配"Maple Valley")
内容的提问来源于stack exchange,提问作者Laila Elmoataz
相关产品推荐
相关产品推荐

