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

如何让Pandas自定义NYSE日历类可迭代?解决下标报错问题

解决NYSECalendar迭代时的TypeError问题

问题场景

尝试实现自定义NYSE日历类的可迭代功能,遍历交易日:

nyse_cal = NYSECalendar()
for date in nyse_cal:
    print(date)

但迭代方法中last_holiday = self.rules[-1]触发TypeError: 'method' is not subscriptable错误。

错误原因

AbstractHolidayCalendar将类属性rules封装成了实例方法(而非直接可访问的列表),因此通过self.rules访问到的是方法对象,无法进行下标操作[-1]。此外,原代码中last_holiday.dates[-1]也存在问题:Holiday的dates是生成日期的方法,并非预存的日期列表,不能直接取下标。

修复方案

关键修改点

  1. 直接访问类的rules属性:用self.__class__.rules[-1]替代self.rules[-1],直接获取类定义中的假期规则列表。
  2. 正确生成假期日期:调用Holiday.dates()方法并指定日期范围,获取该假期的最近日期。
  3. 调整迭代范围逻辑:设定合理的起始/结束日期(或允许用户传入),避免依赖不确定的假期日期计算。

修改后的完整代码

from pandas.tseries.offsets import CustomBusinessDay, MonthEnd
from pandas.tseries.holiday import AbstractHolidayCalendar, Holiday, \
    USMemorialDay, USMartinLutherKingJr, USPresidentsDay, GoodFriday, \
    USLaborDay, USThanksgivingDay, nearest_workday, next_monday
import pandas as pd

class NYSECalendar(AbstractHolidayCalendar):
    ''' NYSE holiday calendar via pandas '''
    rules = [
        Holiday('New Years Day', month=1, day=1, observance=nearest_workday),
        USMartinLutherKingJr,
        USPresidentsDay,
        GoodFriday,
        USMemorialDay,
        Holiday('Juneteenth', month=6, day=19, observance=nearest_workday),
        Holiday('USIndependenceDay', month=7, day=4, observance=nearest_workday),
        USLaborDay,
        USThanksgivingDay,
        Holiday('Christmas', month=12, day=25, observance=nearest_workday),
    ]
    
    def __iter__(self, start_year=2023, end_year=2024):
        # 获取类定义中的最后一条假期规则
        last_holiday_rule = self.__class__.rules[-1]
        # 生成该假期在指定结束年份的日期
        last_holiday_date = last_holiday_rule.dates(start=pd.Timestamp(f'{end_year}-01-01'), 
                                                    end=pd.Timestamp(f'{end_year}-12-31'))[-1]
        
        # 计算迭代的起始和结束日期(示例:结束年份的下一年第一个交易日到年末最后一个交易日)
        start_date = pd.Timestamp(f'{end_year + 1}-01-01') + CustomBusinessDay(calendar=self)
        end_date = pd.Timestamp(f'{end_year + 1}-12-31') - CustomBusinessDay(calendar=self)
        
        curr_date = start_date
        while curr_date <= end_date:
            yield curr_date
            curr_date += CustomBusinessDay(calendar=self)

# 测试迭代
nyse_cal = NYSECalendar()
for date in nyse_cal(start_year=2023, end_year=2024):
    print(date)

可选优化

  • 允许用户在实例化或调用迭代时传入自定义的起始/结束日期,增强灵活性。
  • 若要遍历历史交易日,可调整起始日期为更早的年份。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.30 21:48:21