Python3号Pandas的假期在pas中找不到任意时段的日期

2024-09-22 14:36:55 发布

您现在位置:Python中文网/ 问答频道 /正文

我自己对MLK日假期的定义,并不是指这个节日是什么时候开始的,而是指纽约证交所什么时候开始的。纽约证交所第一次庆祝MLK日是在1998年1月

当向假日询问日期之间发生假日的天数时,它在大多数情况下都可以正常工作,当MLK日期不在请求的范围内时返回一个空集,当它在请求的范围内时返回适当的日期。对于假日的start_date之前的日期范围,它适当地返回空集,直到我们到达1995年左右,然后它就失败了。当空集是正确的答案时,我不明白为什么它会失败,在其他情况下也不会

注:仍停留在0.22.0。Python3

import pandas as pd
from datetime import datetime
from dateutil.relativedelta import MO
from pandas.tseries.holiday import Holiday

__author__ = 'eb'

mlk_rule = Holiday('MLK Day (NYSE Observed)',
                   start_date=datetime(1998, 1, 1), month=1, day=1,
                   offset=pd.DateOffset(weekday=MO(3)))

start = pd.to_datetime('1999-01-17')
end = pd.to_datetime('1999-05-01')
finish = pd.to_datetime('1980-01-01')
while start > finish:
    print(f"{start} - {end}:")
    try:
        dates = mlk_rule.dates(start, end, return_name=True)
    except Exception as e:
        print("\t****** Fail *******")
        print(f"\t{e}")
        break
    print(f"\t{dates}")
    start = start - pd.DateOffset(years=1)
    end = end - pd.DateOffset(years=1)

运行时,这将导致:

1999-01-17 00:00:00 - 1999-05-01 00:00:00:
    1999-01-18    MLK Day (NYSE Observed)
Freq: 52W-MON, dtype: object
1998-01-17 00:00:00 - 1998-05-01 00:00:00:
    1998-01-19    MLK Day (NYSE Observed)
Freq: 52W-MON, dtype: object
1997-01-17 00:00:00 - 1997-05-01 00:00:00:
    Series([], dtype: object)
1996-01-17 00:00:00 - 1996-05-01 00:00:00:
    Series([], dtype: object)
1995-01-17 00:00:00 - 1995-05-01 00:00:00:
    ****** Fail *******
    Must provide freq argument if no data is supplied

1995年发生了什么导致它失败的事情,而在过去几年的同一时期却没有发生


Tags: tofromimportdatetimeobjectstartendpd
1条回答
网友
1楼 · 发布于 2024-09-22 14:36:55

答:在Holiday类中,dates()方法用于 收集请求日期范围内的有效假日列表。在 为了确保正确发生这种情况,实现 要求日期前一年至后一年的所有假期 通过内部_reference_dates()方法的范围。在这种方法中, 如果接收Holiday实例有内部开始或结束日期, 它使用该日期作为要检查的范围的开始或结束 而不是传入请求的范围,即使请求的 范围早于或超过规则的开始或结束日期

现有的实现错误地假设可以限制有效范围,必须准确地识别存在哪些假日,将其限制在存在假日的范围内。作为日历中一组规则的一部分,对于Holiday来说,识别哪里不存在假日和哪里不存在假日一样重要。空集响应是Holiday类的一个重要函数

例如,在需要确定金融市场何时开放或关闭的交易日日历中,日历可能需要准确确定市场在100年历史中关闭的日期。在那段历史的一小部分时间里,市场只在MLK日休市。包含上述MLK假日的日历在请求MLKstart_date[1]之前时段的开放日或假日时抛出错误

为了解决这个问题,我在一个 自定义子类的假期,以确保当要求的日期 范围在start_date之前或end_date之后扩展 假日规则,它使用实际请求的范围来构建 引用日期从,而不是由内部 开始和结束日期

这是我正在使用的实现

class MLKHoliday(Holiday):

def __init__(self):
    super().__init__('MLK Day (NYSE Observed)',
                     start_date=datetime(1998, 1, 1), month=1, day=1,
                     offset=pd.DateOffset(weekday=MO(3)))

def _reference_dates(self, start_date, end_date):
    """
    Get reference dates for the holiday.

    Return reference dates for the holiday also returning the year
    prior to the start_date and year following the end_date.  This ensures
    that any offsets to be applied will yield the holidays within
    the passed in dates.
    """
    if self.start_date and start_date and start_date >= self.start_date:
        start_date = self.start_date.tz_localize(start_date.tz)

    if self.end_date and end_date and end_date <= self.end_date:
        end_date = self.end_date.tz_localize(end_date.tz)

    year_offset = pd.DateOffset(years=1)
    reference_start_date = pd.Timestamp(
        datetime(start_date.year - 1, self.month, self.day))

    reference_end_date = pd.Timestamp(
        datetime(end_date.year + 1, self.month, self.day))
    # Don't process unnecessary holidays
    dates = pd.DatetimeIndex(start=reference_start_date,
                             end=reference_end_date,
                             freq=year_offset, tz=start_date.tz)
    return dates

有人知道这一点是否已经在最新版本的熊猫中得到了解决

[1]注意:正如在原始问题中构造的,mlk_rule实际上不会在start_date之前的范围内为dates()调用提供空集,但实际上会在一年左右之前开始抛出异常。这是因为关于不需要适当的空集响应的错误假设通过在每个方向上将日期范围延长一年而减轻了_reference_dates()

相关问题 更多 >