#python #pandas #function #dataframe #datetime
#python #pandas #функция #фрейм данных #datetime
Вопрос:
Я пытаюсь создать дополнительный столбец во фрейме данных, чтобы показать количество сетевых дней (за исключением пользовательских праздников) между двумя датами. Я использую функцию, которой я пытаюсь передать даты из df
столбцов в качестве аргументов, но я не могу заставить ее работать.
Ниже приведен мой код (я использую два выдуманных праздника в данном наборе):
from networkdays import networkdays
import datetime as dt
import numpy as np
import pandas as pd
public_holidays_list = [dt.date(2021, 1, 6), dt.date(2021, 1, 7)]
public_holidays = set(public_holidays_list)
def working_days(start, end, holidays):
days = networkdays.Networkdays(start, end, holidays)
working_days = len(days.networkdays())
return working_days
Сама формула работает нормально:
print(working_days(dt.date(2021, 1, 4), dt.date(2021, 1, 8), public_holidays))
3
Минимальный фрейм данных с тем dtypes
, над которым я работаю:
d = {'Name': ['A', 'B'], 'Start_Date': [dt.date(2021, 1, 4), dt.date(2021, 1, 11)], 'End_Date': [dt.date(2021, 1, 8), dt.date(2021, 1, 15)]}
df = pd.DataFrame(data = d)
df['Start_Date'] = pd.to_datetime(df['Start_Date'])
df['End_Date'] = pd.to_datetime(df['End_Date'])
Когда я пытаюсь использовать приведенный ниже способ…
df['Working_Days'] = working_days(df['Start_Date'], df['End_Date'])
…Я получаю сообщение об ошибке:
Ошибка атрибута: объект ‘Series’ не имеет атрибута ‘days’
Я также пытался использовать numpy
:
df['Working_Days'] = np.vectorize(working_days)(df['Start_Date'], df['End_Date'])
Я также получил ошибку:
Ошибка атрибута: объект ‘numpy.timedelta64’ не имеет атрибута ‘days’
Не могли бы вы указать мне правильное направление?
РЕДАКТИРОВАТЬ: правильный ответ на мою проблему — последний комментарий @Kris.
ВАЖНО!Хотя lambda
он не возвращает никаких ошибок, он public_holidays
правильно учитывает 2 сценария:
A) Элементы public_holidays
относятся к классу datetime.date
, а df
даты относятся к классу object
(я получил это, удалив pd.to_datetime()
строки из кода).
Б) public_holidays
Имеет тип list
(создается из таблицы Excel с помощью public_holidays = df_ph['Date'].tolist()
), его элементы имеют класс Timestamp
, а pd.to_datetime()
строки не удаляются из приведенного выше кода (ввод дат df
datetime64[ns]
).
Комментарии:
1. Найдите apply . Например,
df['Working_Days'] = df.apply(lambda x: working_days(x.Start_Date, x.End_Date), axis=1)
может сработать.2.
@Kris
, теперь он вычисляет дни, но без учета государственных праздников. Я обновил функцию третьим аргументом — можете ли вы сказать мне, как я могу передать егоlambda
, поскольку он находится «снаружи» фрейма данных?3. Добавьте .dt к каждому из ваших аргументов
4. @Witherfield вы должны иметь возможность просто передать его как обычно, например
df.apply(lambda x: working_days(x.Start_Date, x.End_Date, public_holidays), axis=1)
. Я бы написал полный ответ, но я не могу использоватьnetworkdays
.5. @Kris, это действительно работает, спасибо! Не могли бы вы опубликовать свой комментарий в качестве ответа, чтобы я мог его принять?
Ответ №1:
Согласно моему комментарию, используйте .apply
:
df['Working_Days'] = df.apply(lambda x: working_days(x.Start_Date, x.End_Date, public_holidays), axis=1)