You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Pandas Grouper日期值异常:分组后为何返回原数据不存在的日期?

解决Pandas时间序列分组:获取每月实际存在的最晚日期及对应值

这是个很常见的Pandas时间序列分组误区,我来帮你拆解清楚问题所在和对应的解决办法~

为什么groupby(pd.Grouper(freq='M')).last()会返回月末日期?

你观察到的现象其实是pd.Grouper(freq='M')的设计逻辑导致的:

  • 当你用freq='M'作为分组依据时,Pandas会自动将所有时间戳归组到当月的最后一个日历日(比如4月的所有数据都会被分到2017-04-30这个组标签下),不管你的原始数据里有没有这个日期。
  • last()方法确实会取每组内原始数据的最后一条记录的值,但分组后的结果索引会被替换成预设的组标签(也就是月末日期),并不是Pandas把4月28日的值“映射”到了4月30日,只是索引被替换成了分组的标准标签而已。

为什么groupby(pd.Grouper(freq='M')).max()不符合需求?

max()方法是对每一列分别取最大值:

  • 对日期列(或索引),它会取组内的最大日期;但对CumReturn列,它会取组内的最大值。
  • 这就导致结果可能是组内CumReturn最大的那行,而不是日期最晚的那行(比如你4月的数据里,4/4的CumReturn是100,是最大值,所以max()会返回这行,和你要的“最晚日期”需求不匹配)。

正确的解决方法:保留原始的最晚日期

要获取每月实际存在数据的最晚日期及对应值,我们可以换一种分组方式,直接按月份周期分组,而不是按月末日历日分组:

import pandas as pd

# 读取并预处理数据(注意要正确设置索引)
df = pd.read_clipboard(parse_dates=['Date'])
df = df.set_index('Date')  # 这里必须赋值,否则索引不会修改

# 按月份周期分组,取每组的最后一行(保留原始日期)
result = df.groupby(df.index.to_period('M')).apply(lambda x: x.iloc[-1])

运行后你会得到符合预期的结果:

DateCumReturn
2017-03-311.000
2017-04-281.012
2017-05-311.022
2017-06-301.033

方法原理:

  • df.index.to_period('M')会把每个时间戳转换成对应的月份周期(比如2017-04),这样分组的依据是“月份”而非“月末日期”。
  • apply(lambda x: x.iloc[-1])直接取每组内的最后一条记录,保留了原始数据的日期索引和对应的值,完全符合你的需求。

内容的提问来源于stack exchange,提问作者Evan

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 07:29:07