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

Pandas子串匹配实现多值关键词标注(Python)

高效匹配Pandas DataFrame标签的解决方案(适用于大规模数据集)

针对大规模数据集,逐行循环匹配关键词效率极低,我们需要采用向量化或优化的关键词匹配方法。以下是两种实用方案,可根据你的关键词数量规模选择:


方案一:基于正则表达式的向量化匹配(适合中小规模关键词集)

这种方法利用Pandas的向量化字符串操作,避免Python层面的逐行循环,性能优于普通迭代。

步骤说明:

  1. 构建关键词到标签的映射(用集合避免单个关键词内的标签重复)
  2. 生成匹配所有关键词的正则表达式(转义特殊字符防止正则语法冲突)
  3. 提取每个短语中所有匹配的关键词
  4. 聚合标签并去重,合并回原DataFrame

代码示例:

import pandas as pd
import re

# 示例数据
df1 = pd.DataFrame({'phrase': ['苹果派配苹果', '香蕉面包', '樱桃挞', '橙汁', '混合莓果冰沙']})
df2 = pd.DataFrame({
    'keyword': ['苹果', '香蕉', '派', '挞', '莓果'],
    'tag1': ['水果', '水果', '烘焙', '烘焙', '水果'],
    'tag2': ['甜点', '甜点', '甜点', '甜点', '饮品']
})

# 1. 构建关键词-标签映射(集合自动去重单个关键词的重复标签)
keyword_tag_map = df2.set_index('keyword').apply(
    lambda row: {row['tag1'], row['tag2']}, axis=1
).to_dict()

# 2. 生成正则模式(转义关键词中的特殊字符)
escaped_keywords = [re.escape(k) for k in keyword_tag_map.keys()]
# 若需匹配完整单词,添加\b边界:pattern = r'\b(' + '|'.join(escaped_keywords) + r')\b'
pattern = '|'.join(escaped_keywords)

# 3. 提取所有匹配的关键词
matches = df1['phrase'].str.extractall(f'({pattern})')[0].reset_index()
matches.columns = ['phrase_idx', 'match_order', 'keyword']

# 4. 聚合标签并去重
matches['tags'] = matches['keyword'].map(keyword_tag_map)
aggregated_tags = matches.groupby('phrase_idx')['tags'].apply(
    lambda x: set().union(*x)  # 合并所有匹配关键词的标签并去重
).reset_index()

# 转换为可读字符串,空匹配则设为空字符串
aggregated_tags['tags_str'] = aggregated_tags['tags'].apply(
    lambda x: ', '.join(sorted(x)) if x else ''
)

# 合并回原DataFrame
df1 = df1.merge(
    aggregated_tags[['phrase_idx', 'tags_str']],
    left_index=True, right_on='phrase_idx',
    how='left'
).drop('phrase_idx', axis=1).fillna({'tags_str': ''})

print(df1)

方案二:基于Flashtext的匹配(适合大规模关键词集)

当关键词数量超过1万条时,正则表达式的性能会显著下降,此时Flashtext是更好的选择。它基于字典树(Trie)结构,匹配时间复杂度为O(n)(n为文本长度),与关键词数量无关,效率远超正则。

步骤说明:

  1. 安装并导入Flashtext库
  2. 初始化关键词处理器,添加关键词及对应标签集合
  3. 批量提取每个短语的匹配标签,聚合去重

代码示例:

import pandas as pd
from flashtext import KeywordProcessor

# 示例数据同方案一
df1 = pd.DataFrame({'phrase': ['苹果派配苹果', '香蕉面包', '樱桃挞', '橙汁', '混合莓果冰沙']})
df2 = pd.DataFrame({
    'keyword': ['苹果', '香蕉', '派', '挞', '莓果'],
    'tag1': ['水果', '水果', '烘焙', '烘焙', '水果'],
    'tag2': ['甜点', '甜点', '甜点', '甜点', '饮品']
})

# 1. 初始化关键词处理器(case_sensitive=False表示不区分大小写)
kp = KeywordProcessor(case_sensitive=False)

# 2. 添加关键词及对应标签集合
for _, row in df2.iterrows():
    kp.add_keyword(row['keyword'], {row['tag1'], row['tag2']})
    # 若需匹配完整单词,添加word_boundaries=True:
    # kp.add_keyword(row['keyword'], {row['tag1'], row['tag2']}, word_boundaries=True)

# 3. 提取并聚合标签
df1['tags'] = df1['phrase'].apply(
    lambda x: set().union(*kp.extract_keywords(x)) if kp.extract_keywords(x) else set()
)

# 转换为可读字符串
df1['tags_str'] = df1['tags'].apply(
    lambda x: ', '.join(sorted(x)) if x else ''
)

print(df1)

关键注意事项:

  • 特殊字符处理:正则方案中用re.escape()转义关键词中的特殊字符(如.、*等),避免正则语法错误;Flashtext会自动处理特殊字符。
  • 大小写敏感性:两种方案都可通过参数设置是否区分大小写。
  • 完整单词匹配:若需匹配完整单词而非子串,正则方案添加\b边界,Flashtext设置word_boundaries=True。
  • 空值处理:最终结果中无匹配的短语标签设为空字符串,符合需求。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.09 20:03:11