Как добавить рабочие дни в день, исключая праздничные дни - PullRequest
1 голос
/ 08 января 2020

У меня есть фрейм данных (df) со столбцами start_date и add_days (= 10). Я хочу создать target_date (=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'])

, но я получаю эту ошибку:

AttributeError: у объекта 'Series' нет атрибута 'weekday'

Спасибо за помощь.

1 Ответ

0 голосов
/ 08 января 2020

Комментарии 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).

Надеюсь, это поможет!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...