Использование Pandas выходных / праздничных диапазонов для фильтрации даты и времени - PullRequest
1 голос
/ 03 марта 2020

Я пытался использовать функцию pandas 'Праздники для почасовых данных, чтобы получить логический массив numpy, в котором все 24 часа праздника возвращаются как Ложные. Я сделал эту работу с df.apply (), но это не очень эффективно. Код ниже:

import pandas as pd
from pandas.tseries.holiday import Holiday, nearest_workday
from dateutil.relativedelta import MO
from dataclasses import dataclass

dt = pd.date_range(start='1/1/2019', end='12/31/2019', freq='H')

@dataclass
class Custom_Holidays:
    # todo: rework; Holiday object has start_date and end_date
    labor_day = Holiday('Labor Day', month=9, day=1, offset=pd.DateOffset(weekday=MO(1)))
    independence_day = Holiday('Independence Day', month=7, day=4)

holidays = Custom_Holidays()

# this only filters out 1 hour instead of 24 hours
independence_day_mask = ~dt.isin(holidays.independence_day.dates(dt[0], dt[-1]))
labor_day_mask = ~dt.isin(holidays.labor_day.dates(dt[0], dt[-1]))

# tests fail -- this should filter out
assert len(dt) - np.sum(independence_day_mask*1) == 24
assert len(dt) - np.sum(independence_day_mask*1) == 24

Я думаю, что это связано с применением маски против часовых значений, а не дневных значений, но все же, я думаю, это должно сработать.

1 Ответ

1 голос
/ 03 марта 2020

Проверьте это . Надеюсь это поможет. В основном, здесь праздничная дата преобразуется в диапазон часовых частот

dt = pd.date_range(start='1/1/2019', end='12/31/2019', freq='H')

class Custom_Holidays(AbstractHolidayCalendar):
    # todo: rework; Holiday object has start_date and end_date
    rules = [Holiday('Labor Day', month=9, day=1, offset=pd.DateOffset(weekday=MO(1))),
             Holiday('Independence Day', month=7, day=4)]

holiday_df = pd.date_range(start=1/1/2019, periods=24, freq='H')
holidays = Custom_Holidays().holidays(dt.min().date(), dt.max().date())

# for the holidays make it as a range of hourly freq
for day in holidays:
    holiday_df = holiday_df.append(pd.date_range(day, day + pd.DateOffset(hours=23), freq='H'))

holiday_mask = ~dt.isin(holiday_df)
print(len(dt) - np.sum(holiday_mask*1)) # this will give you 48 (24 + 24 for 2 days as holidays)
...