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

Pandas按日分组(非连续日期)出现分组错误问题排查

解决Pandas按DatetimeIndex分组时生成空分组的问题

问题背景

你有一个以DatetimeIndex为索引的DataFrame,尝试按日(freq="D")分组时,Pandas会自动填充首尾日期之间的所有日期,生成大量空分组,导致自定义聚合函数因访问空分组的索引而抛出IndexError。而按月/年分组看似正常,只是因为你的数据刚好覆盖了连续的月份/年份,没有空区间。

解决方案

要实现仅基于实际存在数据的频率区间分组,可以直接将索引按目标频率格式化后作为分组键,避免Pandas自动填充空区间。

1. 按任意频率分组(通用方法)

使用index.floor()方法将DatetimeIndex按目标频率向下取整,以此作为分组依据:

按日分组

import pandas as pd

df = pd.DataFrame(
    data={"values": [10.0, 20.0, 10.0, 20.0]},
    index=[pd.Timestamp("2023-01-02T01:00", tz="utc"),
        pd.Timestamp("2023-01-02T02:00", tz="utc"),
        pd.Timestamp("2023-02-03T01:00", tz="utc"),
        pd.Timestamp("2023-02-03T02:00", tz="utc"),],
)

# 仅对存在数据的日期分组
groups = df.groupby(df.index.floor('D'))

按其他频率分组

  • 按5日分组:df.groupby(df.index.floor('5D'))
  • 按月(每月第一天)分组:df.groupby(df.index.floor('MS'))
  • 按季度分组:df.groupby(df.index.floor('QS'))

2. 运行自定义聚合函数

现在你的聚合函数可以正常执行,不会遇到空分组:

def f(group):
    d = {}
    d['new_col'] = str(group.index[0]) + "/" + str(group.index[-1])
    return pd.Series(d)

new_df = groups.apply(f)

最终结果

new_col
2023-01-02 00:00:00+00:00  2023-01-02 01:00:00+00:00/2023-01-02 02:00:00+00:00
2023-02-03 00:00:00+00:00  2023-02-03 01:00:00+00:00/2023-02-03 02:00:00+00:00

原理说明

使用pd.Grouper(freq="D")时,Pandas会生成从数据最早日期到最晚日期的所有连续日区间,即使区间内没有数据也会保留,这就是你得到33个分组的原因。而通过index.floor()生成分组键时,只会将属于同一频率区间的现有数据归为一组,完全不会创建空分组,从根源避免了索引越界问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.28 19:53:16