解决Jupyter Notebook中自定义节假日重复添加至USFederalHolidayCalendar的问题
解决USFederalHolidayCalendar重复添加自定义节假日的问题
我通过for循环给USFederalHolidayCalendar添加自定义节假日,代码如下:
from IPython.display import clear_output from datetime import date from pandas.tseries.holiday import Holiday, USFederalHolidayCalendar custom_holiday_dates = [ (date(2024,12,24), 'Christmas Eve'), (date(2025,1,9), 'National Day of Mourning for Carter') ] cal = USFederalHolidayCalendar() for custom_date, holiday_name in custom_holiday_dates: clear_output(wait=True) cal.rules.append(Holiday(holiday_name, month=custom_date.month, day=custom_date.day, year=custom_date.year))
每次重新运行单元格时,自定义节假日会被重复添加,必须重启内核才能避免。试过clear_output和%autoreload都无效,重新运行后cal.rules的输出如下:
[Holiday: New Year's Day (month=1, day=1, observance=<function nearest_workday at 0x000001594D82EF20>), Holiday: Birthday of Martin Luther King, Jr. (month=1, day=1, offset=<DateOffset: weekday=MO(+3)>), Holiday: Washington's Birthday (month=2, day=1, offset=<DateOffset: weekday=MO(+3)>), Holiday: Memorial Day (month=5, day=31, offset=<DateOffset: weekday=MO(-1)>), Holiday: Juneteenth National Independence Day (month=6, day=19, observance=<function nearest_workday at 0x000001594D82EF20>), Holiday: Independence Day (month=7, day=4, observance=<function nearest_workday at 0x000001594D82EF20>), Holiday: Labor Day (month=9, day=1, offset=<DateOffset: weekday=MO(+1)>), Holiday: Columbus Day (month=10, day=1, offset=<DateOffset: weekday=MO(+2)>), Holiday: Veterans Day (month=11, day=11, observance=<function nearest_workday at 0x000001594D82EF20>), Holiday: Thanksgiving Day (month=11, day=1, offset=<DateOffset: weekday=TH(+4)>), Holiday: Christmas Day (month=12, day=25, observance=<function nearest_workday at 0x000001594D82EF20>), Holiday: Christmas Eve (year=2024, month=12, day=24, ), Holiday: National Day of Mourning for Carter (year=2025, month=1, day=9, ), Holiday: Christmas Eve (year=2024, month=12, day=24, ), Holiday: National Day of Mourning for Carter (year=2025, month=1, day=9, )]
问题根源
USFederalHolidayCalendar的rules是类属性,所有实例共享同一个规则列表。直接调用cal.rules.append()会修改类的规则集合,导致后续每次运行代码都会重复添加自定义节假日。
解决方案
方案1:创建自定义日历子类(推荐)
通过继承原日历类并扩展规则,隔离自定义规则与原类,每次实例化子类都会得到干净的规则集合:
from datetime import date from pandas.tseries.holiday import Holiday, USFederalHolidayCalendar class CustomUSCalendar(USFederalHolidayCalendar): rules = USFederalHolidayCalendar.rules + [ Holiday('Christmas Eve', month=12, day=24, year=2024), Holiday('National Day of Mourning for Carter', month=1, day=9, year=2025) ] # 每次运行都实例化子类,规则不会重复 cal = CustomUSCalendar()
方案2:复制默认规则再添加自定义
复制原类的默认规则到实例独立的列表中,避免修改原类的共享规则:
from datetime import date from pandas.tseries.holiday import Holiday, USFederalHolidayCalendar custom_holiday_dates = [ (date(2024,12,24), 'Christmas Eve'), (date(2025,1,9), 'National Day of Mourning for Carter') ] cal = USFederalHolidayCalendar() # 复制规则列表,让实例拥有独立的规则集合 cal.rules = cal.rules.copy() for custom_date, holiday_name in custom_holiday_dates: cal.rules.append(Holiday(holiday_name, month=custom_date.month, day=custom_date.day, year=custom_date.year))
方案3:检查规则是否已存在再添加
如果需要在原实例上操作,可通过节假日名称检查避免重复添加:
from datetime import date from pandas.tseries.holiday import Holiday, USFederalHolidayCalendar custom_holiday_dates = [ (date(2024,12,24), 'Christmas Eve'), (date(2025,1,9), 'National Day of Mourning for Carter') ] cal = USFederalHolidayCalendar() # 收集已存在的节假日名称 existing_holiday_names = {holiday.name for holiday in cal.rules} for custom_date, holiday_name in custom_holiday_dates: if holiday_name not in existing_holiday_names: cal.rules.append(Holiday(holiday_name, month=custom_date.month, day=custom_date.day, year=custom_date.year)) existing_holiday_names.add(holiday_name)
内容的提问来源于stack exchange,提问作者swilson
相关产品推荐
相关产品推荐

