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

如何让Pandas的resample函数在非24小时可整除的时间区间下与日期对齐?

如何让Pandas的resample函数在非24小时可整除的时间区间下与日期对齐?

我完全懂你遇到的困扰——用5小时这种没法整除24的区间重采样时,一开始还好好的,结果到第二天时段就跑偏了,完全不是你想要的固定整点窗口。其实这是因为Pandas默认的resample是连续滚动的时间窗口,24除以5没法得到整数,所以窗口会从起始时间一直累加,到第二天自然就偏移了;而像2h、4h这种能整除24的区间,刚好能把一天分成整数个窗口,所以每天都能对齐到整点。

想要实现你要的固定时段(00-05、05-10、10-15、15-20、20-次日00),咱们可以换个思路——给数据打时段标签,按固定时段分组聚合,而不是依赖默认的连续滚动窗口。下面给你两种实用的方法:

方法一:自定义时段分组(推荐,完全匹配需求)

这种方法直接根据数据的小时数,把每条数据归到对应的每日固定时段里,20点之后的数据直接关联到次日的时段标签,确保每天的窗口都对齐。

import pandas as pd

# 假设你的原始数据是read,且索引是datetime类型
read['date'] = read.index.date
read['hour'] = read.index.hour

# 定义函数:给每条数据分配时段和对应的基准日期
def get_period_info(row):
    if 0 <= row['hour'] < 5:
        return (row['date'], '00:00-05:00')
    elif 5 <= row['hour'] < 10:
        return (row['date'], '05:00-10:00')
    elif 10 <= row['hour'] < 15:
        return (row['date'], '10:00-15:00')
    elif 15 <= row['hour'] < 20:
        return (row['date'], '15:00-20:00')
    else:  # 20:00到次日00:00的时间段
        return (row['date'] + pd.Timedelta(days=1), '20:00-00:00')

# 生成分组键
read['period_key'] = read.apply(get_period_info, axis=1)

# 按分组键聚合,用你需要的聚合规则
agg_rules = {'Open': 'first', 'High': 'max', 'Low': 'min', 'Close': 'last'}
df = read.groupby('period_key').agg(agg_rules)

# 调整索引格式,让结果更清晰
df.index = pd.MultiIndex.from_tuples(df.index, names=['Date', 'Period'])
print(df)

这样处理后,你会得到完全对齐的每日时段:当天20点到次日0点的数据会被归到次日的20:00-00:00时段(如果你想把它归到当天的最后一个时段,只需要把函数里的日期改成row['date']就行)。

方法二:生成固定时段边界后重采样

如果你更习惯用resample的思路,可以先手动生成所有需要的固定时段边界,再把数据映射到对应的窗口里:

import pandas as pd

# 确保原始数据索引是datetime类型,且无时区(避免时区干扰)
read = read.tz_localize(None)

# 生成所有每日时段的起始边界
start_date = read.index.min().floor('D')
end_date = read.index.max().ceil('D')
daily_dates = pd.date_range(start=start_date, end=end_date, freq='D')

period_starts = []
for date in daily_dates:
    # 每天添加5个固定起始点
    period_starts.extend([
        date,
        date + pd.Timedelta(hours=5),
        date + pd.Timedelta(hours=10),
        date + pd.Timedelta(hours=15),
        date + pd.Timedelta(hours=20)
    ])
# 去重并排序边界
period_starts = sorted(list(set(period_starts)))

# 把数据切割到对应的时段窗口
read['period_label'] = pd.cut(
    read.index,
    bins=period_starts,
    labels=[s.strftime('%Y-%m-%d %H:%M') for s in period_starts[:-1]]
)

# 按时段标签聚合
agg_rules = {'Open': 'first', 'High': 'max', 'Low': 'min', 'Close': 'last'}
df = read.groupby('period_label').agg(agg_rules)
# 把标签转回datetime索引
df.index = pd.to_datetime(df.index)
print(df)

这个方法会提前创建好所有你需要的固定时段窗口,再把数据“装”进去聚合,结果同样能完美对齐你要的每日时段。

总结一下:当重采样区间无法整除24小时时,默认的连续滚动窗口必然会偏移,所以咱们需要主动定义每日固定的时段边界,通过分组聚合来实现对齐需求,而不是依赖resample的默认行为。

备注:内容来源于stack exchange,提问作者x_crypto

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.14 14:33:09