Перекрытие двух периодов времени - PullRequest
0 голосов
/ 14 января 2019

У меня есть два кадра данных.

В этом поле указано время рабочей смены с датой начала и окончания.

Другим является «время простоя», которое имеет время начала и время окончания.

Оба кадра данных выглядят следующим образом:

    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 секунду, и результат все еще был другим).

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

Большое спасибо

1 Ответ

0 голосов
/ 15 января 2019

Исходя из запрошенного примера в комментариях, и с условием, что время простоя может фактически выходить за пределы рабочих часов смены (что кажется неправильным, но, эй, это ваши данные), вы можете найти общее время, отработанное за четыре часа с этими шаги:

>>> from datetime import datetime
>>> fmt = '%Y-%m-%d %H:%M:%S'
>>> S1 = datetime.strptime('2018-01-02 06:00:00', fmt)
>>> E1 = datetime.strptime('2018-01-02 18:30:00', fmt)
>>> S2 = datetime.strptime('2018-01-02 10:00:00', fmt)
>>> E2 = datetime.strptime('2018-01-02 20:00:00', fmt)

>>> shift = max(E1, E2) - min(S1, S2)
>>> downtime = E2 - S2
>>> worked = shift - downtime
>>> worked.seconds
14400
>>> worked.seconds / 60 / 60
4.0
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...