У меня есть два кадра данных.
В этом поле указано время рабочей смены с датой начала и окончания.
Другим является «время простоя», которое имеет время начала и время окончания.
Оба кадра данных выглядят следующим образом:
Start Date End Date
43 2018-10-01 05:00:00+00:00 2018-10-03 05:00:00+00:00
44 2018-09-27 13:00:00+00:00 2018-10-01 05:00:00+00:00
45 2018-09-27 10:10:00+00:00 2018-09-27 13:00:00+00:00
Я пытаюсь выяснить, сколько времени на самом деле работают сотрудники. Только время, которое не является временем простоя, должно учитываться.
Я подумал о двух способах решения этой проблемы (которые дают несколько разные результаты)
Первый - это «метод грубой силы», в котором я создаю новый фрейм данных, содержащий запись каждой минуты в году. Я соединил это с рабочим временем, чтобы все рабочее время было разделено на 1-минутные интервалы. Затем я использовал следующий код
removed_stuff = pd.DataFrame(columns=["shift","columns"])
for i in range(len(downtime)):
removed_stuff = pd.concat([removed_stuff,test_copy[(test_copy.index <= downtime["End Date"][i]) & (test_copy.index >= downtime["Start Date"][i])]])
test_copy = test_copy[(test_copy.index > downtime["End Date"][i]) | (test_copy.index < downtime["Start Date"][i])]
remove_stuff - это все то, что было удалено из времени начала и окончания запланированного_запуска_режима. test_copy - это то, что я хочу, и оно содержит все время вне времени простоя.
При суммировании количества минут test_copy я (должен) получить общее количество минут, которые были вне любого простоя, который работал.
Моя другая идея немного более волнистая.
Я объединил время простоя и смену рабочих в один кадр данных:
time shift start shift end stoppage start stoppage end
2018-01-02 06:00:00+00:00 NaN NaN 1.0 NaN
2018-01-02 18:30:00+00:00 NaN NaN NaN 1.0
2018-01-04 06:00:00+00:00 1.0 NaN NaN NaN
2018-01-04 18:00:00+00:00 NaN 1.0 NaN NaN
2018-01-05 06:00:00+00:00 1.0 NaN NaN NaN
2018-01-05 18:00:00+00:00 NaN 1.0 NaN NaN
Затем я создаю новый столбец, который записывается следующим образом.
def actaul_shift(Dataframe,first_value):
Dataframe_new = Dataframe.copy()
Dataframe_new["actual"][0] = first_value
for i in range(len(Dataframe_new)):
if i != 0:
if Dataframe_new["shift start"][i] == 1:
Dataframe_new["actual"][i] = Dataframe_new["actual"][i - 1] + 1
elif Dataframe_new["shift end"][i] == 1:
Dataframe_new["actual"][i] = Dataframe_new["actual"][i -1] - 1
elif Dataframe_new["stoppage start"][i] == 1:
Dataframe_new["actual"][i] = Dataframe_new["actual"][i -1] - 1
elif Dataframe_new["stoppage end"][i] == 1:
Dataframe_new["actual"][i] = Dataframe_new["actual"][i -1] + 1
return Dataframe_new
Я должен указать самое первое значение (то есть, должен ли аппарат быть включен или выключен в первый момент времени), после этого, если начало смены == 1, тогда фактическая колонка должна добавить 1 к предыдущему значению, если конец смещения == 1, то минус 1 к предыдущему значению, если начало остановки == 1, то минус 1 к предыдущему значению, а если конец остановки == 1, то добавить 1 к предыдущему значению.
По сути, мне важно только, когда число переходит от 1 к 0 (включено-выключено).
Если машина запускается в выключенном состоянии (0), затем начинается время простоя (-1), затем начинается смена (0), затем время простоя заканчивается (1), а затем смена заканчивается (0). учитываются только последние значения от 1 до 0, поскольку в остальное время машина не работала.
Выполнение нескольких примеров на листе бумаги, кажется, всегда имеет смысл.
Однако результаты, которые я получаю от двух методов, дают немного разные результаты. Результаты достаточно велики (на 9% отличаются), и я не могу объяснить это с помощью простых ошибок округления из первого метода (я даже запускал его с интервалами в 1 секунду, и результат все еще был другим).
Является ли любой из этих методов правильным. Если это так, есть ли более эффективный метод, если нет, то есть правильный метод.
Большое спасибо