Как мне компенсировать праздники - панды - PullRequest
1 голос
/ 29 сентября 2019

Допустим, у меня есть фрейм данных следующим образом:

df = pd.DataFrame({'Ending Date': [Timestamp('2019-12-08 00:00:00'), Timestamp('2019-12-08 00:00:00')], 'FName': ['Jon', 'Bob'], 'LName': ['Doe', 'Smith'], 'Starting Date': ['2019-09-29', '2019-09-29']})

  Ending Date FName  LName Starting Date
0  2019-12-07   Jon    Doe    2019-09-28
1  2019-12-07   Bob  Smith    2019-09-28

Как видите, столбцы конечной даты всегда на 10 недель раньше начальной даты, однако яу меня есть список выходных:

holidays = pd.Series([Timestamp('2019-09-14 00:00:00'), Timestamp('2019-10-05 00:00:00'), Timestamp('2019-10-12 00:00:00'), Timestamp('2019-10-26 00:00:00'), Timestamp('2019-12-21 00:00:00'), Timestamp('2019-12-28 00:00:00'), Timestamp('2020-01-04 00:00:00'), Timestamp('2020-01-25 00:00:00'), Timestamp('2020-02-01 00:00:00'), Timestamp('2020-02-29 00:00:00'), Timestamp('2020-04-04 00:00:00'), Timestamp('2020-05-02 00:00:00')])

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

Я пытался:

df['Ending Date'] = df['Ending Date'] + pd.Timedelta(weeks=10 + pd.date_range(df['Starting Date'], df['Ending Date']).isin(holidays).sum())

Но возникает ошибка:

TypeError: Cannot convert input [0    2019-09-28
1    2019-09-28
Name: Starting Date, dtype: object] of type <class 'pandas.core.series.Series'> to Timestamp

.

Желаемый вывод:

  Ending Date FName  LName Starting Date
0  2020-01-18   Jon    Doe    2019-09-28
1  2020-01-18   Bob  Smith    2019-09-28

1 Ответ

1 голос
/ 29 сентября 2019

Я предполагаю, что и Дата начала и Дата окончания должны иметь тип datetime64 [нс] .Если это не так, конвертируйте их в pd.to_datetime .

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

Тогда, чтобы выполнить вашу задачу, будет очень просто, если мы используем Настраиваемый бизнес-календарь , с заданным пользователем праздникомдаты.

Начните с определения CustomBusinessDay смещения, включая ваш список праздников:

my_bday = pd.offsets.CustomBusinessDay(holidays=holidays, weekmask='Sat')

Затем, чтобы вычислить дату n рабочих дней (на самом деле - также за несколько недель) до указанной даты дата , мы должны использовать формулу: dat + 10 * my_bday.

Так что в вашем случае (исходные данные в столбце Starting Date и результат будет сохранен в Дата окончания ), запустите:

df['Ending Date'] = df['Starting Date'].apply(lambda dat: dat + 10 * my_bday)
...