Pandas BDay未识别Juneteenth 如何重写方法使其识别该节假日
问题说明
pandas 1.4.2 版本内置BDay工作日偏移类默认未收录Juneteenth(六月节)节假日。2022年6月17日为周五,执行以下测试代码时,预期结果应为2022-06-21(因6月19日为周日,六月节补休至6月20日周一,需跳过该休假日),实际原生BDay会返回2022-06-20,不符合业务预期。
from datetime import date from pandas.tseries.offsets import BDay date(2022,6,17) + BDay(1)
原生BDay返回错误结果的原因:pandas 1.4.2版本发布时,Juneteenth的联邦假日规则未被内置到默认节假日日历中,因此计算工作日偏移时不会跳过该节日及对应的补休日期。
解决方案
无需重写整个BDay类,直接使用pandas原生支持的CustomBusinessDay自定义工作日类,传入补充了Juneteenth规则的节假日列表即可,兼容性远高于直接修改BDay源码。
Juneteenth为2021年正式生效的美国联邦节假日,固定日期为每年6月19日,补休规则为:若当日为周六则提前至6月18日周五休,若当日为周日则延后至6月20日周一休。
方案1:自定义节假日规则生成偏移类
from datetime import date from pandas.tseries.offsets import CustomBusinessDay from pandas.tseries.holiday import ( Holiday, nearest_workday, USNewYearsDay, USMartinLutherKingJr, USPresidentsDay, USMemorialDay, USLaborDay, USColumbusDay, USVeteransDay, USThanksgivingDay, USChristmasDay ) # 定义六月节规则 USJuneteenth = Holiday( "Juneteenth National Independence Day", month=6, day=19, start_date="2021-06-18", # 限制生效起始年份,避免影响2021年之前的日期计算 observance=nearest_workday # 周末自动调整到最近工作日 ) # 合并所有默认美国联邦节假日 us_federal_holidays = [ USNewYearsDay, USMartinLutherKingJr, USPresidentsDay, USMemorialDay, USJuneteenth, USLaborDay, USColumbusDay, USVeteransDay, USThanksgivingDay, USChristmasDay ] # 生成支持六月节的工作日偏移实例,用法和原生BDay完全一致 US_BDay = CustomBusinessDay(holidays=us_federal_holidays) # 验证结果 print(date(2022,6,17) + US_BDay(1)) # 输出:2022-06-21,符合预期
方案2:扩展内置联邦假日日历
如果已经在使用USFederalHolidayCalendar做日期计算,可以直接给日历追加六月节规则,不用重新组装节假日列表:
from pandas.tseries.holiday import USFederalHolidayCalendar, Holiday, nearest_workday from pandas.tseries.offsets import CustomBusinessDay # 给1.4.2版本内置的联邦假日日历补充六月节规则 USFederalHolidayCalendar.rules.append( Holiday( "Juneteenth National Independence Day", month=6, day=19, start_date="2021-06-18", observance=nearest_workday ) ) # 基于更新后的日历生成工作日偏移 US_BDay = CustomBusinessDay(calendar=USFederalHolidayCalendar()) # 验证结果和方案1一致 print(date(2022,6,17) + US_BDay(1)) # 2022-06-21
使用提示
- 如果仅需要处理固定几个年份的日期计算,也可以直接把对应年份的六月节休市日期以
datetime格式写入CustomBusinessDay的holidays参数,不需要定义完整的Holiday规则 - 不要直接修改pandas安装目录下的BDay源码实现,后续升级pandas版本时修改会失效,还可能引发其他依赖冲突
- 该方案生成的
US_BDay实例接口和原生BDay完全一致,原有代码仅需要替换导入的偏移对象即可,改造成本极低
内容的提问来源于stack exchange,提问作者cpage
相关产品推荐
相关产品推荐

