Как исключить выходные и праздничные дни в расчете длительности на пандах - PullRequest
0 голосов
/ 12 сентября 2018

Вот мой набор данных, чтобы убедиться, что вы знаете формат данных, до этого я сделал

df['Datetime_Start'] =  df['Start'].dt.strftime('%D')
df['Datetime_Finish'] =  df['Finish'].dt.strftime('%D')

Выбранные интересные столбцы

No  Datetime_Start    Datetime_Finish
1   13/08/18          31/08/18
1   14/08/18          25/08/18

Вывод, который я ожидал

No  Datetime_Start    Datetime_Finish    Duration
1   13/08/18          31/08/18           12 Days
1   14/08/18          24/08/18           6 Days

Это потому, что 18, 19, 25 и 26 августа 2018 года - суббота и воскресенье, а 17 и 22 - государственный праздник (в Индонезии)

Это ссылки на государственный праздник в Индонезии https://publicholidays.co.id/2018-dates/, но это нормально, если вы включите 17 и 22 августа 2018 года для ответа на вопрос, но, пожалуйста, сделайте это настраиваемым, чтобы я мог добавить вручную

1 Ответ

0 голосов
/ 12 сентября 2018

Это может быть один из способов.Основная идея заключается в том, что я расширяю диапазон до всех дат между (pd.date_range), а затем использую различные критерии для фильтрации дат, которые не должны учитываться:

import pandas as pd

import requests

from icalendar import Calendar

ics_url = 'https://www.calendarlabs.com/ical-calendar/ics/50/Indonesia_Holidays.ics'

df = {'Datetime_Start': pd.to_datetime(['2018-08-13', '2018-08-14']),
      'Datetime_End': pd.to_datetime(['2018-08-31', '2018-08-25'])}
df = pd.DataFrame(df)

df['days_in_range'] = df.apply(
    lambda x: pd.date_range(x['Datetime_Start'], x['Datetime_End']),
    axis=1)

# remove weekends
df['days_in_range'] = df['days_in_range'].apply(lambda x: x[x.dayofweek <= 4])

# remove holidays
calendar = Calendar.from_ical(requests.get(ics_url).content)
holidays = [pd.to_datetime(x['DTSTART'].dt).date()
            for x in calendar.walk('VEVENT')]

df['days_in_range'] = df['days_in_range'].apply(
    lambda x: [y for y in x if y.date() not in holidays])

df['Duration'] = df['days_in_range'].apply(lambda x: len(x) - 1)

Определенно есть шансы ускорить этои есть также некоторые скрытые предположения:

  • Диапазоны всегда состоят как минимум из одного исчисляемого дня для результата.Угловые случаи не обрабатываются.
  • Предполагается, что файл ical не использует повторение.
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...