Scala中DataFrame匹配关键词列表并生成新列的实现需求
解决方案:从DataFrame文本列批量匹配关键词并生成结果列
刚好处理过类似需求,针对你20k规模的关键词列表,我给你两种实用实现方式,兼顾可读性和效率:
先准备示例数据
先把你的示例DataFrame和关键词列表用代码还原,方便你直接测试:
import pandas as pd # 构建示例DataFrame df = pd.DataFrame({ 'utid': [123, 234], 'description': [ 'my name is harry and I live in newyork', 'my neighbour is daniel and he plays hockey' ] }) # 关键词列表(实际使用时直接替换成你的20k规模列表即可) keyword_list = ['harry', 'daniel', 'hockey', 'newyork']
方法一:apply结合列表推导(逻辑直观,适合中小规模关键词)
这种方式新手也能快速理解,逻辑清晰:
def extract_matched_keywords(text, keywords): # 筛选出文本中包含的所有关键词 matched = [kw for kw in keywords if kw in text] # 匹配到内容就用@连接,否则返回NF return '@'.join(matched) if matched else 'NF' # 将函数应用到description列,生成新列foundornot df['foundornot'] = df['description'].apply(extract_matched_keywords, keywords=keyword_list)
运行后就能得到你想要的结果:
utid description foundornot 0 123 my name is harry and I live in newyork harry@newyork 1 234 my neighbour is daniel and he plays hockey daniel@hockey
方法二:正则批量匹配(效率更高,适配20k大规模关键词)
如果关键词有20k量级,逐行循环检查会比较慢,用正则向量化匹配效率提升明显。这里还可以处理全词匹配需求(避免类似harrypotter被误识别为harry),同时兼容带正则元字符的关键词:
import re # 处理关键词:转义正则元字符,若需要全词匹配就加上单词边界\b # 不需要全词匹配的话,去掉rf'\b{...}\b'里的\b即可 pattern = '|'.join([rf'\b{re.escape(kw)}\b' for kw in keyword_list]) # 批量提取匹配关键词,再处理成@分隔的字符串 df['foundornot'] = df['description'].str.findall(pattern).apply( lambda x: '@'.join(x) if x else 'NF' )
这种方法利用Pandas的向量化字符串操作,比逐行循环快很多,非常适合大规模关键词场景。
额外注意点
- 大小写敏感:如果需要忽略大小写匹配,可以在正则里添加
flags=re.IGNORECASE,或者在检查时统一把文本和关键词转成小写(比如text.lower()和kw.lower())。 - 全词匹配:如果你的关键词是独立词汇(比如不想
newyorkcity被匹配成newyork),一定要保留正则里的\b单词边界。
内容的提问来源于stack exchange,提问作者nitesh jha
相关产品推荐
相关产品推荐

