如何统计文本中的短语并提取高频最长短语?基于DataFrame文本列的技术实现咨询
提取最长高频重复短语的解决方案
嘿,这个需求我之前处理过,核心就是优先匹配最长的短语,避免短子短语被误统计。下面用Python结合pandas和nltk来实现,完全符合你的要求:
思路拆解
要实现“最长匹配+高频(≥2次)”的目标,关键步骤是:
- 先把文本拆成单词,从最长的可能短语长度开始生成候选短语(n-gram)
- 找到符合次数要求的短语后,标记它覆盖的所有单词位置,这样后续更短的子短语就不会重复统计
- 最后筛选出所有符合条件的短语并统计次数
具体实现代码
首先确保安装了依赖:
pip install nltk pandas
然后直接用下面的代码,适配你的数据集:
import pandas as pd from nltk.util import ngrams from collections import defaultdict import re # 你的示例数据集(替换成你实际的df即可) data = {'text': ["text the main goal is to develop a smart calendar the main goal is to develop a smart calendar the main goal is to develop a chat bot it is clear that the main goal is to develop a product ai products for department A launching ai products for department B"]} df = pd.DataFrame(data) # 合并所有文本为一个连续字符串(如果你的df有多行text,这一步会把所有内容整合) full_text = ' '.join(df['text'].tolist()) # 简单清洗:去掉标点,拆分成单词列表 cleaned_text = re.sub(r'[^\w\s]', '', full_text) tokens = cleaned_text.split() # 存储最终结果:短语 -> 出现次数 high_freq_phrases = defaultdict(int) # 记录已经被最长短语覆盖的单词位置,避免短短语重复统计 occupied_positions = set() # 从最长的可能短语长度开始遍历(至少要能出现2次,所以取总单词数的一半) max_phrase_length = len(tokens) // 2 for phrase_length in range(max_phrase_length, 1, -1): # 生成所有该长度的短语,同时记录每个短语的起始位置 phrase_positions = defaultdict(list) for start_idx in range(len(tokens) - phrase_length + 1): current_phrase = ' '.join(tokens[start_idx:start_idx+phrase_length]) phrase_positions[current_phrase].append(start_idx) # 检查每个短语是否符合要求:出现≥2次,且未被已匹配的短语覆盖 for phrase, starts in phrase_positions.items(): if len(starts) >= 2: # 验证该短语的所有出现位置都未被占用 is_valid = True for start in starts: # 该短语覆盖的位置是start到start+phrase_length-1 for pos in range(start, start + phrase_length): if pos in occupied_positions: is_valid = False break if not is_valid: break if is_valid: # 标记所有被该短语覆盖的位置 for start in starts: for pos in range(start, start + phrase_length): occupied_positions.add(pos) # 记录该短语的出现次数 high_freq_phrases[phrase] = len(starts) # 把结果转成DataFrame,方便查看和导出 result_df = pd.DataFrame({ 'text': list(high_freq_phrases.keys()), 'cnt': list(high_freq_phrases.values()) }).sort_values(by='cnt', ascending=False) print(result_df)
代码运行结果
针对你的示例文本,运行后会输出:
text cnt 0 the main goal is to develop 4 1 ai products for department 2
完全和你期望的一致!
注意事项
- 如果你的文本里有特殊符号或标点,代码里的
cleaned_text步骤已经做了基础清洗,你可以根据实际情况调整正则表达式。 - 如果你的df有多行text,代码里的
full_text = ' '.join(df['text'].tolist())会把所有行的文本合并,如果你想单独处理每一行,可以把这部分逻辑改成循环遍历每一行。 - 如果你不想让短语太长,可以手动调整
max_phrase_length的取值,比如设置成10,只检查最多10个单词的短语。
内容的提问来源于stack exchange,提问作者user12314164




