如何在Pandas分组中提取高频Trigram并生成新列
Pandas分组提取高频N元组(通用方案)
需求:按cluster_name分组,为每个组提取出现频率最高的N元组(支持Unigram/Bigram/Trigram灵活切换),输出每个组对应的高频N元组。
示例测试数据
cluster_name keyword 0 summer summer dresses size 10 1 summer summer dresses size 12 2 summer large summer dresses 3 summer summer dresses size 14 4 strappy ladies strappy summer dresses 5 strappy strappy summer dresses uk 2022 6 strappy strappy summer dress 7 strappy strappy summer dresses 8 strappy thin strap summer dresses
期望输出(Trigram为例)
cluster_name trigram 0 summer summer dresses size 1 strappy strappy summer dresses
最小可复现代码
import pandas as pd data = [ ["summer", "summer dresses size 10"], ["summer", "summer dresses size 12"], ["summer", "large summer dresses"], ["summer", "summer dresses size 14"], ["strappy", "ladies strappy summer dresses"], ["strappy", "strappy summer dresses uk 2022"], ["strappy", "strappy summer dress"], ["strappy", "strappy summer dresses"], ["strappy", "thin strap summer dresses"], ] df = pd.DataFrame(data, columns=['cluster_name', 'keyword'])
已尝试方案
现有可运行的Bigram提取代码,但实现粗糙,依赖繁琐的字符串清理步骤,且无法灵活切换N元组类型。
通用解决方案
实现思路
- 编写通用N元组生成函数,支持自定义
n值 - 按分组批量收集所有N元组
- 用
Counter统计频率,提取每个组的最高频N元组 - 整理为目标格式DataFrame
完整代码
from collections import Counter import pandas as pd def generate_ngrams(text, n): """生成文本的所有N元组,返回用空格连接的字符串列表""" words = text.strip().split() # 当文本长度不足n时,返回空列表 if len(words) < n: return [] return [' '.join(words[i:i+n]) for i in range(len(words) - n + 1)] # 切换此处的n值即可提取不同类型的N元组:1=单字词,2=双字词,3=三字词 n = 3 # 分组收集所有N元组 grouped_ngrams = df.groupby('cluster_name')['keyword'].apply( lambda group: [gram for text in group for gram in generate_ngrams(text, n)] ) # 提取每个组的最高频N元组 top_ngrams = grouped_ngrams.apply( lambda gram_list: Counter(gram_list).most_common(1)[0][0] if gram_list else None ) # 转换为目标格式 result = top_ngrams.reset_index().rename(columns={0: f'{n}-gram'}) print(result)
方案优势
- 灵活性高:仅修改
n参数即可切换Unigram/Bigram/Trigram提取 - 健壮性强:避免原方案的字符串清理操作,直接通过统计获取结果
- 效率更优:利用分组批量处理,减少逐行操作的性能开销
内容的提问来源于stack exchange,提问作者Lee Roy
相关产品推荐
相关产品推荐

