Продолжительность разделения, определенная начальной и конечной отметкой времени в часе - PullRequest
1 голос
/ 29 октября 2019

У меня есть данные с отметками времени начала и окончания, например:

              Start               End
0  2019-01-01 00:59  2019-01-01 01:01
1  2019-01-01 01:10  2019-01-01 03:10

И я хочу разделить длительности по часам (то есть, если длительность начинается в 18:59 и заканчивается в 19:05 у нас будет две новые строки, одна из которых начинается в 18:59 и заканчивается в 19:00, а другая начинается в 19:00 и заканчивается в 19:05). Вывод для моего примера dataframe будет:

              Start               End
0  2019-01-01 00:59  2019-01-01 01:00
1  2019-01-01 01:00  2019-01-01 01:01
2  2019-01-01 01:10  2019-01-01 02:00
3  2019-01-01 02:00  2019-01-01 03:00
4  2019-01-01 03:00  2019-01-01 03:10

Я пробовал несколько вещей, используя методы dt.ceil и dt.floor, чтобы выяснить, нужно ли мне разрывать строку или нет, но я могуНе могу придумать плавный способ сделать все преобразования без циклического прохождения строки за строкой.

Кадры данных могут быть созданы со следующими фрагментами:

start = pd.DataFrame({
    'Start': ['2019-01-01 00:59', '2019-01-01 01:10'],
    'End': ['2019-01-01 01:01', '2019-01-01 03:10']
})

finish = pd.DataFrame({
    'Start': ['2019-01-01 00:59', '2019-01-01 01:00', '2019-01-01 01:10', '2019-01-01 02:00', '2019-01-01 03:00'],
    'End': ['2019-01-01 01:00', '2019-01-01 01:01', '2019-01-01 02:00', '2019-01-01 03:00', '2019-01-01 03:10']
})

1 Ответ

2 голосов
/ 29 октября 2019

Используйте listcomp, pd.date_range и создайте серию s из результата date_range. Наконец, создайте final df из s

a = [pd.date_range(s.ceil('H'), e, freq='H').insert(0,s) for s, e in zip(df.Start, df.End)]
s = pd.Series(a, index=df.index).explode()

df_final = (pd.DataFrame({'Start': s, 'End': s.groupby(level=0).shift(-1).fillna(df.End)})
              .reset_index(drop=True))

Out[41]:
                Start                 End
0 2019-01-01 00:59:00 2019-01-01 01:00:00
1 2019-01-01 01:00:00 2019-01-01 01:01:00
2 2019-01-01 01:10:00 2019-01-01 02:00:00
3 2019-01-01 02:00:00 2019-01-01 03:00:00
4 2019-01-01 03:00:00 2019-01-01 03:10:00

Если вы хотите вывести Start и End в строковом формате, просто добавьте strftime

df_final = pd.DataFrame({'Start': s.dt.strftime('%Y-%m-%d %H:%M'), 
                         'End': s.groupby(level=0).shift(-1).fillna(df.End).dt.strftime('%Y-%m-%d %H:%M')})

Out[40]:
              Start               End
0  2019-01-01 00:59  2019-01-01 01:00
0  2019-01-01 01:00  2019-01-01 01:01
1  2019-01-01 01:10  2019-01-01 02:00
1  2019-01-01 02:00  2019-01-01 03:00
1  2019-01-01 03:00  2019-01-01 03:10

Примечание: если ваша версия для панд не поддерживает explode, вы можете использовать df.index.repeat и np.concatenate для создания s

s = pd.Series(np.concatenate(a), index=df.index.repeat(list(map(len, a))))
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...