pandas中时间分组运算最稳方式是用pd.grouper配合groupby或resample:需确保时间列为datetime64类型,可设索引后用pd.grouper(freq='d'),或不改索引时指定key参数;resample适用于等频聚合(如每日均值),但会丢原始行,且必须设时间列为索引。

直接用 pandas.Grouper 配合 resample 或 groupby 是最稳的路,别手写时间切片逻辑——容易漏边界、时区错乱、或把跨天数据劈断。
用 pd.Grouper 按固定周期分组(如每天/每小时)
这是最常用也最可靠的自动拆分方式,前提是你的时间列是 datetime64 类型且已设为索引,或明确传入 key 参数。
常见错误:直接对字符串时间列 groupby('time'),结果按字面值分组,不是按时间周期。
- 先确保时间列类型正确:
df['timestamp'] = pd.to_datetime(df['timestamp']) - 设为索引后用
Grouper:df.set_index('timestamp').groupby(pd.Grouper(freq='D')).apply(...) - 不想改索引?用
key:df.groupby(pd.Grouper(key='timestamp', freq='2H')) -
freq支持'D'(日)、'W'(周)、'M'(月末)、'MS'(月初)、'30T'(30分钟)等,注意'M'和'MS'行为差异很大
用 resample 做等频重采样(适合聚合,不保留原始行)
resample 本质是带时间对齐的 groupby,但默认会丢原始行、只留聚合结果。如果目标是“拆成多个子集”,它不如 Grouper 直观;但如果要统计每日均值、每小时最大值,它更简洁。
典型误用:对非数值列直接 resample('D').sum(),报 TypeError: dtype datetime64[ns] not supported。
- 必须先设时间列为索引:
df.set_index('timestamp').resample('D').mean() - 混合类型列?用
agg显式指定:.resample('D').agg({'value': 'mean', 'category': 'first'}) - 想保留原始数据结构?别用
resample,回到Grouper+apply(list)或list(group)
手动切分时绕不开的三个坑
有人坚持用布尔索引(如 df[(df.t >= '2023-01-01') & (df.t ),短期可行,但长期维护成本高,尤其涉及夏令时、时区、不规则周期时极易出错。
- 时间字符串没带时区,但数据实际是 UTC:
pd.to_datetime('2023-01-01')默认本地时区,和df.timestamp.dt.tz_localize('UTC')对不上 - 用
strftime截日期再分组?df['date'] = df.timestamp.dt.strftime('%Y-%m-%d')→ 类型变 object,后续无法做时间运算,也丢失精度 - 跨年/跨月切分用
between_time?它只看时分秒,忽略日期,完全不适合按天拆分
真正难的不是写哪一行代码,而是确认你的「周期起点」在哪——比如按自然日切分,但业务要求从中午12点开始算一天,这时 freq='D' 就不对了,得用 freq='24H' 加 origin 参数,或者自定义 offset。这个细节几乎没人查文档,但一出问题就很难定位。
Python免费学习笔记(深入):立即使用
在学习笔记中,你将探索 Python 的核心概念和高级技巧!











