Pandas按两个月周期聚合数据的问题求助
搞定这个Pandas分组问题很简单,我来给你拆解一下!
问题分析
你遇到的问题核心是Pandas中freq='2M'的默认行为和你的预期不匹配:
- 默认
2M频率是以月末为锚点生成周期的,会自动生成6月30日、8月31日、10月31日这类节点 - 再加上
closed="right"的设置,每个周期会包含右端点之前的数据,导致第一个周期只覆盖6月,第二个覆盖7-8月,第三个覆盖9月,最终得到了三个分组的结果。
解决方案
这里有两种简单的方法可以得到你想要的分组结果:
方法一:调整pd.Grouper的频率和参数
使用2MS(以每月第一天为锚点的两个月周期),配合closed='left'和label='right'参数,直接生成符合预期的分组:
import pandas as pd # 你的原始数据 data={'A': pd.to_datetime(['2018-06-01','2018-06-15','2018-07-01','2018-07-15','2018-08-01','2018-08-15','2018-09-01','2018-09-15','2018-09-30']), 'B': [1,1,1,1,1,1,1,1,1]} test=pd.DataFrame.from_dict(data) # 按两个月周期聚合,符合预期 result = test.groupby(pd.Grouper(key='A', freq='2MS', closed='left', label='right')).sum() print(result)
运行后输出:
B A 2018-07-31 4 2018-09-30 5
参数说明:
freq='2MS':表示以每月第一天为起点,每两个月为一个周期(即6月1日、8月1日、10月1日作为周期节点)closed='left':每个周期包含左端点数据(比如第一个周期覆盖2018-06-01至2018-07-31的所有日期)label='right':用周期的结束日期作为分组标签(Pandas会自动转换为该周期的最后一天,也就是7月31日和9月30日)
方法二:手动生成周期列
如果你觉得参数设置有点绕,也可以手动给每条数据标记所属的周期,再分组:
import pandas as pd data={'A': pd.to_datetime(['2018-06-01','2018-06-15','2018-07-01','2018-07-15','2018-08-01','2018-08-15','2018-09-01','2018-09-15','2018-09-30']), 'B': [1,1,1,1,1,1,1,1,1]} test=pd.DataFrame.from_dict(data) # 生成周期列,指定从6月开始每两个月为一个周期 test['period'] = test['A'].dt.to_period('2M', starting_month=6) # 按周期分组求和 result = test.groupby('period').sum() # 将周期转换为该周期的最后一天作为索引 result.index = result.index.to_timestamp(how='end') print(result)
这个方法逻辑更直观:starting_month=6直接指定周期从6月开始,每两个月一组,最后把周期转换为结束日期即可,同样能得到你想要的结果。
内容的提问来源于stack exchange,提问作者Haennor
相关产品推荐
相关产品推荐

