如何在熊猫的持续时间计算中排除周末和假期

Nab*_*zir 1 python timestamp dataframe pandas

这是我的数据集,为了确保您知道数据格式,在此之前我做了

df['Datetime_Start'] =  df['Start'].dt.strftime('%D')
df['Datetime_Finish'] =  df['Finish'].dt.strftime('%D')
Run Code Online (Sandbox Code Playgroud)

选定的有趣栏目

No  Datetime_Start    Datetime_Finish
1   13/08/18          31/08/18
1   14/08/18          25/08/18
Run Code Online (Sandbox Code Playgroud)

我期望的输出

No  Datetime_Start    Datetime_Finish    Duration
1   13/08/18          31/08/18           12 Days
1   14/08/18          24/08/18           6 Days
Run Code Online (Sandbox Code Playgroud)

这是因为2018年8月18日、19日、25日和26日是周六和周日,17日和22日是公共假期(印度尼西亚)

这是印度尼西亚公共假期的链接https://publicholidays.co.id/2018-dates/,但如果您只包括 2018 年 8 月 17 日和 22 日来回答问题就可以了,但请将此设置为可配置的,以便我可以手动添加

lan*_*tar 5

这可能是一种方式。基本思想是我将范围扩展到 ( 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)
Run Code Online (Sandbox Code Playgroud)

肯定有机会加快速度,也有一些隐藏的假设:

  • 范围始终包含至少一个可计算的结果天数。不处理角落案件。
  • 假设 ical 文件不使用重复。