Смещение Pandas CustomBusinessDay работает только на некоторые праздники - PullRequest
2 голосов
/ 16 апреля 2019

Я пытаюсь вычислить 5-й рабочий день в будущем, основываясь на слегка настроенном календаре.Тем не менее, значения для Дня труда (выходной день в сентябре в США) рассчитываются неправильно, в то время как значения для месяцев января и июля (другие месяцы, на которые может повлиять выходной день) рассчитаны правильно.

У меня естьуже пытался использовать dts + 5 * custom_bday - но это просто перемещает проблему с неверных значений Sept на отключение значений на январь и июль на один день.

import pandas as pd
from datetime import datetime

start = datetime(2019,1,1)
end = datetime(2024,8,1)
dtrange = pd.date_range(start, end, freq='MS')
dts = pd.Series(dtrange)

hols = holidays.UnitedStates(state='MD', years=[2019,2020,2021,2022,2023,2024])
notholidays = ['American Indian Heritage Day', 'Columbus Day', 'Veterans Day']
realhols = [i for i in sorted(hols.items()) if i[1] not in notholidays]
realholsdt = [i[0] for i in realhols]

custom_bday = pd.offsets.CustomBusinessDay(holidays=realholsdt)

dts + 4 * custom_bday

Ожидаемые результаты - серия 5-го рабочего дня каждого месяца, исключая выходные и праздничные дни.Однако все праздники Дня труда (в сентябре) не работают, например,

Просмотр: 8 2019-09-06

Ожидание: 8 2019-09-09

1 Ответ

0 голосов
/ 01 мая 2019

Вы можете получить первый рабочий день месяца через CustomBusinessMonthBegin, в то время как CustomUSHolidayCalendar. В своем пользовательском календаре убедитесь, что вы правильно смещаете LabourDay (если это то, что вам нужно), и добавьте / удалите все праздники. Используйте его в вашем date_range, добавив его к аргументу freq.

import pandas as pd
from datetime import datetime, timedelta

from pandas.tseries.offsets import CustomBusinessMonthBegin, BDay
from pandas.tseries.holiday import (
    AbstractHolidayCalendar, DateOffset,
    Holiday, MO, nearest_workday,
    USLaborDay, USMemorialDay, USColumbusDay, USThanksgivingDay,
    USPresidentsDay, EasterMonday, USMartinLutherKingJr
)

class CustomUSHolidayCalendar(AbstractHolidayCalendar):
    rules = [
        Holiday('New Years Day', month=1, day=1, observance=nearest_workday),
        USMartinLutherKingJr,
        USPresidentsDay,
        USMemorialDay,
        Holiday('July 4th', month=7, day=4, observance=nearest_workday),

        # offset labor day
        Holiday('Labor Day', month=9, day=5, offset=DateOffset(weekday=MO(1))),

        # Holiday('Veterans Day', month=11, day=11, observance=nearest_workday),
        USThanksgivingDay,
        Holiday('Christmas', month=12, day=25, observance=nearest_workday),
        Holiday('Columbus Day', month=10, day=1, offset = pd.DateOffset(weekday=MO(2))),
    ]

start_date = datetime(2019, 1, 1)
end_date = datetime(2024, 8, 1)

usholidays = CustomUSHolidayCalendar()
# US Labor day as 2019-09-09

print(usholidays.holidays(start_date, datetime(2019, 12, 1)))

custom_bday_us = CustomBusinessMonthBegin(calendar=CustomUSHolidayCalendar())
bday_over_df = pd.date_range(start=start_date,
                             end=end_date,
                             freq=custom_bday_us)

Наконец, компенсировать первый рабочий день на 4 рабочих дня.

print(bday_over_df + 4*BDay())

DatetimeIndex(['2019-01-08', '2019-02-07', '2019-03-07', '2019-04-05',
               '2019-05-07', '2019-06-07', '2019-07-05', '2019-08-07',
               '2019-09-06', '2019-10-07', '2019-11-07', '2019-12-06',
               '2020-01-08', '2020-02-07', '2020-03-06', '2020-04-07',
               '2020-05-07', '2020-06-05', '2020-07-07', '2020-08-07',
               '2020-09-07', '2020-10-07', '2020-11-06', '2020-12-07',
               '2021-01-08', '2021-02-05', '2021-03-05', '2021-04-07',
               '2021-05-07', '2021-06-07', '2021-07-07', '2021-08-06',
               '2021-09-07', '2021-10-07', '2021-11-05', '2021-12-07',
               '2022-01-07', '2022-02-07', '2022-03-07', '2022-04-07',
               '2022-05-06', '2022-06-07', '2022-07-07', '2022-08-05',
               '2022-09-07', '2022-10-07', '2022-11-07', '2022-12-07',
               '2023-01-09', '2023-02-07', '2023-03-07', '2023-04-07',
               '2023-05-05', '2023-06-07', '2023-07-07', '2023-08-07',
               '2023-09-07', '2023-10-06', '2023-11-07', '2023-12-07',
               '2024-01-08', '2024-02-07', '2024-03-07', '2024-04-05',
               '2024-05-07', '2024-06-07', '2024-07-05', '2024-08-07'],
              dtype='datetime64[ns]', freq=None)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...