ОТВЕТ: Внутри класса Holiday
метод dates()
используется для
собрать список действительных праздников в пределах запрашиваемого диапазона дат. В
Чтобы убедиться, что это происходит правильно, реализация собирает
все праздники от одного года до одного года после запрошенной даты
диапазон по внутреннему методу _reference_dates()
. В этом методе
если получающий экземпляр Holiday
имеет внутреннюю дату начала или окончания,
эта дата используется в качестве начала или конца исследуемого диапазона
вместо того, чтобы передать в запрошенном диапазоне, даже если даты в запрошенном
диапазон, предшествующий или превышающий дату начала или окончания правила.
Существующая реализация ошибочно предполагает, что можно ограничить эффективный диапазон, в котором она должна точно определить, какие существуют праздники, диапазоном, в котором существуют праздники. Как часть набора правил в календаре, Holiday
так же важно определить, где не существует праздников, как и то, где они существуют. Ответ NULL set является важной функцией класса Holiday
.
Например, в Календаре торговых дней , который должен определять, когда финансовые рынки открыты или закрыты, календарю может потребоваться точно определить, в какие дни рынок закрыт за 100-летнюю историю. Рынок закрылся только на день МЛК для небольшой части этой истории. Календарь, который включает праздничные дни MLK, как построено выше, выдает ошибку при запросе дней открытых дверей или праздничных дней для периодов, предшествующих MLK start_date
[1].
Чтобы исправить это, я повторно реализовал метод _reference_dates()
в
Пользовательский подкласс Holiday, чтобы гарантировать, что, когда запрашиваемая дата
диапазон расширяется до 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
фактически не сможет предоставить NULL, установленный для вызова dates()
, в диапазоне, предшествующем start_date
, но фактически начнет генерировать исключения a год или около того до этого. Это связано с тем, что ошибочное предположение об отсутствии необходимости в правильном ответе набора NULL смягчается расширением диапазона дат на год в каждом направлении на _reference_dates()
.