Панды - Получение рабочих часов между датой и текущим временем - PullRequest
0 голосов
/ 29 мая 2018

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

Мой текущий код для получения данных междудва столбца даты работает .

df выглядит следующим образом (создан столбец даты, созданный с помощью pd.datetime.now():

Index   Created Date        Updated Date        Diff Hrs    Current Date
10086   2016-11-04 16:00:00 2016-11-11 11:38:00 35.633333   2018-05-29 10:09:11.291391
10087   2016-11-04 16:03:00 2016-11-29 12:54:00 132.850000  2018-05-29 10:09:11.291391
10088   2016-11-04 16:05:00 2016-11-16 08:05:00 56.916667   2018-05-29 10:09:11.291391
10089   2016-11-04 16:17:00 2016-11-08 11:37:00 11.333333   2018-05-29 10:09:11.291391
10090   2016-11-04 16:20:00 2016-11-16 09:58:00 57.633333   2018-05-29 10:09:11.291391
10091   2016-11-04 16:32:00 2016-11-08 11:10:00 10.633333   2018-05-29 10:09:11.291391

Рабочий код для получения разницы между Created Date иUpdated Date ниже:

import datetime
import pytz
import businesstimedelta
import holidays as pyholidays

workday = businesstimedelta.WorkDayRule(
    start_time=datetime.time(9),
    end_time=datetime.time(17),
    working_days=[0, 1, 2, 3, 4])


vic_holidays = pyholidays.AU(prov='VIC')
holidays = businesstimedelta.HolidayRule(vic_holidays)
businesshrs = businesstimedelta.Rules([workday, holidays])

def BusHrs(start, end):
    return businesshrs.difference(start,end).hours+float(businesshrs.difference(start,end).seconds)/float(3600)

df['Diff Hrs'] = df.apply(lambda row: BusHrs(row['Created Date'], row['Updated Date']), axis=1)   

Требуется некоторое время для запуска, но это работает - однако попытка создать новый столбец из разницы между текущим временем и обновленным временем, например. df['Time Since Last Update'] = df.apply(lambda row: BusHrs(row['Current Date'], row['Updated Date']), axis=1) завершается неудачно / занимает вечно иЯ понятия не имею, почему.

Любая помощь в расчете Time Since Last Update очень ценится.

1 Ответ

0 голосов
/ 29 мая 2018

Вам нужно инвертировать row['Current Date'] и row['Updated Date'] в вашем df['Time Since Last Update'], тогда с

df['Time Since Last Update'] = df.apply(lambda row: BusHrs(row['Updated Date'], row['Current Date']), axis=1)

это должно работать.Я предполагаю, что start не может быть после end в функции businesshrs.difference.Кроме того, если вы хотите немного ускорить ваш код, выполните:

def BusHrs(start, end):
    diff_businesshrs = businesshrs.difference(start,end)
    # like this you calculate only once businesshrs.difference(start,end)
    return diff_businesshrs.hours+float(diff_businesshrs.seconds)/float(3600)

РЕДАКТИРОВАТЬ Я думаю, я нашел более быстрый путь.Поскольку рабочие часы между вещами с 2016 года по настоящее время являются длинными для подсчета для каждой строки, я думаю, что вы можете сделать это быстрее, рассчитав часы между двумя последовательными Дата обновления и затем sum по этим частичным вычислениям до текущей даты.Вам нужны два временных столбца, один со смещенной датой обновления, а другой с неполными рабочими часами

df = df.sort_values('Updated Date').reset_index()
df['Shift Date'] = df['Updated Date'].shift(-1).fillna(pd.datetime.now())
df['BsnHrs Partial'] = df.apply(lambda row: BusHrs(row['Updated Date'], row['Shift Date']), axis=1)
df['Time Since Last Update'] = df.apply(lambda row: df['BsnHrs Partial'][row.name:].sum(), axis=1)
df = df.drop(['Shift Date','BsnHrs Partial'],1).set_index('index') # drop and reindex
df = df.sort_index() #if you want to go back to the original order
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...