Офсетът на Pandas CustomBusinessDay работи само за някои празници

Опитвам се да изчисля 5-ия работен ден в бъдещето въз основа на леко персонализиран календар. Въпреки това стойностите за Деня на труда (празник в САЩ през септември) се изчисляват неправилно, докато стойностите за месеците януари и юли (другите месеци, потенциално засегнати от празник) се изчисляват правилно.

Вече се опитах да използвам dts + 5 * custom_bday - но това просто премества проблема от стойностите за септември, които са неправилни, към стойностите за януари и юли да са намалени с един ден.

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


person RFADS    schedule 16.04.2019    source източник


Отговори (1)


Можете да получите първия работен ден от месеца до CustomBusinessMonthBegin, като отчитате CustomUSHolidayCalendar. Във вашия персонализиран календар се уверете, че сте компенсирали правилно LaborDay (ако това е, което искате) и добавете/премахнете всички празници. Използвайте го във вашия 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)
person Chris    schedule 01.05.2019