Pandas按年月分组生成聚合表后如何将缺失月份补为0值?
解决方案
核心思路是在现有聚合结果的基础上,补全每个年份的1-12月索引,缺失值填充为0,以下提供两种可直接运行的实现方案:
方案1:reindex补全索引(推荐,无需修改原数据)
import pandas as pd # 你的原始数据 df = pd.DataFrame({ 'year': [2013,2013,2014,2014], 'month': [6,8,1,2], 'abc': [80,40,25,60], 'xyz': [250,-5,15,80] }) # 1. 按year、month分组聚合求和 agg_df = df.groupby(['year', 'month']).sum() # 2. 构造完整的[年份+月份]多级索引 all_years = agg_df.index.get_level_values('year').unique() full_multi_index = pd.MultiIndex.from_product( [all_years, range(1, 13)], names=['year', 'month'] ) # 3. 重排索引,缺失月份填充0 result = agg_df.reindex(full_multi_index, fill_value=0)
方案2:分类类型自动补全(代码更简洁)
将month列设为固定取值范围的分类类型,分组时会自动保留所有月份的维度:
import pandas as pd df = pd.DataFrame({ 'year': [2013,2013,2014,2014], 'month': [6,8,1,2], 'abc': [80,40,25,60], 'xyz': [250,-5,15,80] }) # 将month设置为分类类型,固定取值为1-12 df['month'] = pd.Categorical(df['month'], categories=range(1,13), ordered=True) # 分组时关闭仅统计出现过的类别的参数,缺失值填充0 result = df.groupby(['year', 'month'], observed=False).sum().fillna(0)
注意:Pandas 2.0及以上版本
groupby默认observed=True,必须加observed=False才会保留所有分类维度。
两种方案输出的结果完全符合预期,每个年份都会包含1-12月所有月份,无数据的月份对应值为0。
内容的提问来源于stack exchange,提问作者vvv
相关产品推荐
相关产品推荐

