Pandas如何按月分组统计DataFrame中词列表对应分数均值
Pandas按月份分组统计词语对应Score均值实现方案
核心逻辑:避免逐词循环,先对每行Message内的词语去重(同一行重复出现的词仅统计1次,避免重复计入该行Score),再将词语拆分到独立行,最后分组聚合计算均值即可。
完整实现代码
首先构造示例测试数据:
import pandas as pd # 示例原始数据 df = pd.DataFrame({ 'Message': [["a", "a", "b", "c"], ["a", "b", "d", "e"], ["b", "b", "d", "e"]], 'Score': [5, 4, 4], 'Month': [1, 1, 1] }) # 目标词语列表 target_words = ["a", "b", "c", "d", "e"]
核心处理流程:
# 1. 对每行Message的词语去重,避免同个词在同一行多次出现导致重复统计 df['word'] = df['Message'].apply(lambda x: list(set(x))) # 2. 将列表形式的词语拆分为单独行,每行对应一个词语 df_explode = df.explode('word') # 3. 仅保留目标词列表范围内的词语 df_explode = df_explode[df_explode['word'].isin(target_words)] # 4. 按月份、词语分组计算Score均值,保留2位小数匹配预期格式 result = df_explode.groupby(['Month', 'word'], as_index=False)['Score'].mean().round(2) # 调整列名和要求一致 result.columns = ['month', 'word', 'avg_score']
运行后输出结果:
month word avg_score 0 1 a 4.50 1 1 b 4.33 2 1 c 5.00 3 1 d 4.00 4 1 e 4.00
注:你给出的预期结果中d、e的均值标注为4.5属于注释笔误,按照需求规则(词语出现在哪几行就取哪几行的Score计算均值),d、e仅出现在Score为4的第2、3行,正确均值为4.0。
可选扩展:补全所有月份+目标词组合
如果需要保证每个月都展示全部目标词的统计结果,哪怕某个词当月没有在任何Message中出现,可以用如下代码补全索引,缺失值默认显示NaN:
from itertools import product # 生成所有月份+目标词的完整组合索引 full_pair = pd.MultiIndex.from_tuples( product(df['Month'].unique(), target_words), names=['month', 'word'] ) # 重索引补全缺失组合 result = result.set_index(['month', 'word']).reindex(full_pair).reset_index()
原有代码问题说明
你之前的写法存在两个局限:
- 没有加入Month维度的分组逻辑,只能统计全量数据的均值
- 逐词循环遍历+逐次过滤DataFrame的写法执行效率低,数据量较大时运行速度慢
上面给出的explode+groupby的写法是pandas原生向量化实现,执行效率更高,逻辑也更清晰。
内容的提问来源于stack exchange,提问作者rbar1
相关产品推荐
相关产品推荐

