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

使用Pandas BusinessHour重采样DataFrame时遇ValueError的原因与解决

问题分析与解决方案

异常原因

这个ValueError: Values falls after last bin的问题,本质是**BusinessHour(或频率代码BH)的工作机制和你的数据时间范围不匹配**:

  • 默认的BusinessHour严格遵循周一至周五的9:00-17:00时段划分时间区间,每个区间都是完整的工作小时。
  • 你从yfinance获取的5分钟级数据,大概率包含了超出这个默认工作时段的记录(比如阿姆斯特丹交易所的ABN.AS交易时段可能到17:30,或是带有盘后数据)。当这些超出时段的时间戳出现时,resample无法找到对应的BusinessHour区间来分配它们,就会抛出“值落在最后一个区间之后”的错误。
  • 而Hour偏移是连续的时间区间,不管是否属于工作日或工作时段,所有时间戳都能找到对应的小时区间,因此不会触发错误。

可行的解决办法

1. 先过滤出工作日工作时段的数据,再按小时重采样

这是最稳妥的方案:先把数据限制在你需要的工作日时段内,再用常规的小时重采样。

import yfinance as yf
import pandas as pd

# 获取原始数据
mydata = yf.Ticker('ABN.AS').history(interval='5m', period='1mo', start='2020-06-01')

# 过滤条件:工作日(weekday<5,0=周一,4=周五)+ 工作时段(可根据交易所实际时间调整)
mask = (mydata.index.weekday < 5) & (mydata.index.hour >= 9) & (mydata.index.hour < 18)
# 若需精确到分钟(比如到17:30),可补充:& ~((mydata.index.hour ==17) & (mydata.index.minute >30))
filtered_data = mydata[mask]

# 按小时重采样取均值
mydatahour = filtered_data.resample('H').mean()

2. 自定义BusinessHour的时段范围

如果你的数据确实需要覆盖默认工作时段外的时间(比如早开盘或晚收盘),可以自定义BusinessHour的start和end参数,确保所有数据的时间戳都在这个范围内:

from pandas.tseries.offsets import BusinessHour

# 自定义工作时段为9:00-17:30,匹配交易所实际交易时间
custom_bh = BusinessHour(start='09:00', end='17:30')
# 重采样
mydatahour = mydata.resample(custom_bh).mean()

⚠️ 注意:如果数据中仍有超出这个自定义时段的记录,还是会触发同样的错误,建议结合第一步的过滤操作。

3. 结合Grouper与过滤逻辑

如果你想用groupby+Grouper的方式,同样需要先过滤数据:

# 先过滤数据
filtered_data = mydata[(mydata.index.weekday <5) & (mydata.index.hour.between(9,17))]
# 按工作日小时分组取均值
mydatahour2 = filtered_data.groupby(pd.Grouper(freq='H')).mean()

补充说明

关于你提到的Hour偏移是只读无法调整的问题:其实不需要修改Hour对象,通过先过滤数据的方式,就可以实现“仅在工作日时段重采样到小时级”的需求,效果和用BusinessHour一致,且更灵活可控。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.08 12:48:12