使用pd.groupby()与pd.Grouper()按日期分组时组数异常问题
原因与解决办法
核心原因
GroupBy.groups的打印异常:你看到的#4输出存在明显格式错误,比如索引1(对应2020-01-03的mango记录)被错误归属到2020-09的分组,这是打印时的格式混乱或复制错误,并非分组逻辑问题。实际g.groups包含所有存在数据的分组键,直接打印list(g.groups)即可看到正确结果:
输出会和#5聚合结果的索引完全一致:print(list(g.groups))[(Timestamp('2020-01-01 00:00:00'), 'mango'), (Timestamp('2020-01-01 00:00:00'), 'orange'), (Timestamp('2020-09-01 00:00:00'), 'banana'), (Timestamp('2020-09-01 00:00:00'), 'mango'), (Timestamp('2020-09-01 00:00:00'), 'orange'), (Timestamp('2020-12-01 00:00:00'), 'banana'), (Timestamp('2020-12-01 00:00:00'), 'orange')]groups的显示逻辑:GroupBy.groups仅返回包含至少一条原始数据的分组,不会显示空分组(即某月份没有对应水果的记录时,不会生成该分组)。而聚合操作(如sum())会正确整理所有存在数据的分组,因此能显示完整的有效组合。
如何生成包含空分组的完整结果
如果需要显示所有月份+所有水果的笛卡尔积分组(包括空分组,值填0),可以按以下步骤操作:
import pandas as pd # 1. 修改Grouper,保留空时间分组 p = pd.Grouper(freq='1MS', key='date', dropna=False) # 2. 按时间和水果分组并聚合 g = df.groupby([p, 'fruits']) result = g.sum() # 3. 生成完整的多索引:所有月份 × 所有水果 full_index = pd.MultiIndex.from_product([ pd.date_range(start='2020-01-01', end='2020-12-01', freq='1MS'), df['fruits'].unique() ], names=['date', 'fruits']) # 4. 对齐结果,空分组填充0 result_full = result.reindex(full_index, fill_value=0) print(result_full)
运行后会输出所有可能的(date, fruits)组合,空分组的price值为0。
内容的提问来源于stack exchange,提问作者Nilesh Ingle
相关产品推荐
相关产品推荐

