基于列表匹配多字符串并为每个匹配生成DataFrame新行的需求
解决方案
核心思路
通过正则表达式匹配list_1的所有出现,同时捕获其后可选的连续list_2、list_3元素,再用extractall提取所有匹配项并展开为多行,最后合并回原DataFrame。
步骤与代码实现
构建正则模式:
用单词边界\b确保匹配完整单词,同时通过非捕获组实现list_2、list_3的可选连续匹配(顺序为list_1 → list_2 → list_3)。提取所有匹配:
使用str.extractall提取文本中所有符合模式的匹配,该方法会自动为每个匹配生成一行。合并与整理结果:
将提取的匹配结果与原DataFrame的text列合并,整理列顺序并替换空值为NaN。
import pandas as pd import re # 定义匹配列表 list_1 = ['chest', 'test', 'west', 'nest'] list_2 = ['mike', 'bike', 'like', 'pike'] list_3 = ['hay', 'day', 'may', 'say'] # 构建样例DataFrame sample_df = pd.DataFrame({ 'text': [ 'zzz zzz zz chest bike day zzzz z test mike zzz zzzz west zzz zz', 'aaa aa aaa a nest aa aaaa aaa nest bike may aaaa aaa', 'ggg gg ggg ggg ggg test like hay ggg gg west ggg gggg west like' ], 'match_1': ['chest', 'nest', 'test'], 'match_2': ['bike', pd.NA, 'like'], 'match_3': ['day', pd.NA, 'hay'] }) # 生成各列表的正则备选字符串(转义特殊字符) pat1 = '|'.join(re.escape(item) for item in list_1) pat2 = '|'.join(re.escape(item) for item in list_2) pat3 = '|'.join(re.escape(item) for item in list_3) # 构建正则模式:匹配list_1,后面可选跟list_2(list_2后可选跟list_3) pattern = rf'\b(?P<match_1>{pat1})\b(?:\s+\b(?P<match_2>{pat2})\b(?:\s+\b(?P<match_3>{pat3})\b)?)?' # 提取所有匹配项 matches = sample_df['text'].str.extractall(pattern) # 重置索引,保留原行关联关系 matches = matches.reset_index(level=1, drop=True).reset_index() # 合并原文本列并整理顺序 result = matches.merge(sample_df[['text']], left_on='index', right_index=True) result = result[['text', 'match_1', 'match_2', 'match_3']] # 将空字符串替换为NaN result = result.replace('', pd.NA) print(result)
输出结果
执行代码后,将得到与期望完全一致的DataFrame:
| text | match_1 | match_2 | match_3 |
|---|---|---|---|
| zzz zzz zz chest bike day zzzz z test mike zzz zzzz west zzz zz | chest | bike | day |
| zzz zzz zz chest bike day zzzz z test mike zzz zzzz west zzz zz | test | mike | NaN |
| zzz zzz zz chest bike day zzzz z test mike zzz zzzz west zzz zz | west | NaN | NaN |
| aaa aa aaa a nest aa aaaa aaa nest bike may aaaa aaa | nest | NaN | NaN |
| aaa aa aaa a nest aa aaaa aaa nest bike may aaaa aaa | nest | bike | may |
| ggg gg ggg ggg ggg test like hay ggg gg west ggg gggg west like | test | like | hay |
| ggg gg ggg ggg ggg test like hay ggg gg west ggg gggg west like | west | NaN | NaN |
| ggg gg ggg ggg ggg test like hay ggg gg west ggg gggg west like | west | like | NaN |
内容的提问来源于stack exchange,提问作者user22391597
相关产品推荐
相关产品推荐

