Python中判断时间变量是否在交易日序列中失败的排查求助
问题描述
有时我们需要获取原始时间戳后一个月的日期,但由于并非所有日期都是交易日,因此必须进行调整。
我提取了股票收盘价的索引,得到一个包含大量交易日时间戳的时间序列:
trading_day_glossory = stock_close_full.index
现在给定一个datetime格式的变量date,以下函数本应返回一个表示交易日的day变量,但实际并未生效。if条件从未触发,最终日期累加至9999:99:99并报错:
def return_trading_day(day,trading_day_glossory): while True: day = day + relativedelta(days=1) if day in trading_day_glossory: break
我认为时间戳与datetime的比较存在问题,因此将函数的开头部分改写为:
trading_day_glossory = stock_close_full.index trading_day_glossory = trading_day_glossory.to_pydatetime() # Error message: OverflowError: date value out of range
但此修改并未解决问题。我进一步测试了相关变量的特性:
testing1 = trading_day_glossory[20] # returns a datetime variable say 2000-05-08 00:00:00 testing2 = day # returns a datetime variable say 2000-05-07 00:00:00
问题原因与解决方案
核心问题
- 类型不匹配:
stock_close_full.index是pandas.DatetimeIndex类型,Python原生datetime对象和它直接做in判断会失效——两者属于不同类型,即便时间值完全相同,也会被判定为不相等。 to_pydatetime()的局限性:该方法返回的是numpy.datetime64对象数组,并非Python原生datetime的列表,直接用in判断仍有类型匹配问题,甚至可能因数组中存在超出Python datetime范围的时间值抛出OverflowError。- 原函数缺失返回值:原函数仅通过
break终止循环,但没有return语句,无法返回最终找到的交易日。
解决方法
方法1:转换为Python原生datetime集合(推荐)
将DatetimeIndex转为Python原生datetime的集合,集合的in查询效率远高于数组:
def return_trading_day(day, trading_day_glossory): # 转换为Python datetime集合 trading_days_set = set(trading_day_glossory.to_pydatetime()) while True: day = day + relativedelta(days=1) if day in trading_days_set: return day
方法2:利用pandas内置方法(高效无循环)
借助pandas的索引筛选能力,直接找到目标日期之后的第一个交易日,无需逐天循环:
def return_trading_day(day, trading_day_glossory): # 筛选所有大于目标日期的交易日 next_trading_days = trading_day_glossory[trading_day_glossory > day] if not next_trading_days.empty: return next_trading_days[0] # 无后续交易日时抛出异常或返回默认值 raise ValueError("No trading day exists after the given date")
这种方法性能最优,尤其适合交易日数据量较大的场景。
方法3:统一类型为pandas Timestamp
将输入的day转换为pandas.Timestamp类型,与DatetimeIndex的元素类型完全匹配:
import pandas as pd def return_trading_day(day, trading_day_glossory): # 转换为pandas Timestamp day = pd.Timestamp(day) while True: day = day + relativedelta(days=1) if day in trading_day_glossory: return day
内容的提问来源于stack exchange,提问作者simonj
相关产品推荐
相关产品推荐

