如何在日期中添加工作日但排除节假日

4

我有一个数据框(df),其中有start_date和add_days列(=10)。我想创建目标日期 (= start_date + add_days),但要排除周末和节假日(节假日的数据框已给出)。

我进行了一些研究并尝试了以下方法。

from datetime import date,  timedelta
import datetime as dt

df["star_date"] = pd.to_datetime(df["star_date"])
Holidays['Date_holi'] = pd.to_datetime(Holidays['Date_holi'])


def date_by_adding_business_days(from_date, add_days, holidays):
    business_days_to_add = add_days
    current_date = from_date
    while business_days_to_add > 0:
        current_date += datetime.timedelta(days=1)
        weekday = current_date.weekday()
        if weekday >= 5: # sunday = 6
            continue
        if current_date in holidays:
            continue
        business_days_to_add -= 1
    return current_date


#demo:
base["Target_date"]=date_by_adding_business_days(df["start_date"], 10, Holidays['Date_holi'])

但是我遇到了这个错误:

属性错误:'Series' 对象没有 'weekday' 属性

感谢您的帮助。


2
认为你正在寻找pandas.tseries.offsets.CustomBusinessDay。你可以指定一个节假日日历,然后就可以按N天偏移,排除周末和那些节假日。 - ALollz
1
这些文件在这个例子中非常好用。它们展示了如何创建自定义的日期偏移,跳过周五和周六而不是周六/周日(此处不需要),并且允许用户输入节假日列表。您可以将其乘以“N”以跳过“N”天。 - ALollz
我也遇到了同样的问题,下面的解决方案并没有考虑到日期是通过一个df,基本上是一个列表读入的这个事实,因为使用s开始日期不是我们要寻找的。 我想知道如何读取日期列表/系列,并使该函数起作用? - dps
1个回答

1
ALollz的评论非常有价值;在创建日期时自定义只保留问题中定义为工作日的日期将是最佳选择。
但是,我假设您无法预先定义工作日,并且需要使用构建的数据框解决问题。
以下是一个可能的解决方案:
import pandas as pd
import numpy as np
from datetime import timedelta

# Goal is to offset a start date by N business days (weekday + not a holiday)

# Here we fake the dataset as it was not provided
num_row = 1000
df = pd.DataFrame()
df['start_date'] = pd.date_range(start='1/1/1979', periods=num_row, freq='D')
df['add_days'] = pd.Series([10]*num_row)

# Define what is a week day
week_day = [0,1,2,3,4] # Monday to Friday
# Define what is a holiday with month and day without year (you can add more)
holidays = ['10-30','12-24'] 

def add_days_to_business_day(df, week_day, holidays, increment=10):
    '''
       modify the dataframe to increment only the days that are part of a weekday
       and not part of a pre-defined holiday
       >>> add_days_to_business_day(df, [0,1,2,3,4], ['10-31','12-31'])
           this will increment by 10 the days from Monday to Friday excluding Halloween and new year-eve
    '''
    # Increment everything that is in a business day
    df.loc[df['start_date'].dt.dayofweek.isin(week_day),'target_date'] = df['start_date'] + timedelta(days=increment)
    # Remove every increment done on a holiday
    df.loc[df['start_date'].dt.strftime('%m-%d').isin(holidays), 'target_date'] = np.datetime64('NaT')


add_days_to_business_day(df, week_day, holidays)
df
注意: 我没有使用“add_days”列,因为它只是一个重复的值。相反,我在我的函数increment中使用了一个参数,它将增加N天(默认为N = 10)。
希望对您有所帮助!

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接