Группировка нескольких строк даты-времени в один - PullRequest
2 голосов
/ 24 января 2020

У меня есть датафрейм с некоторым интервалом даты и времени. Я пытаюсь объединить их в отдельные события. У меня есть время начала и окончания наряду с соответствующей продолжительностью для каждого события.

Что у меня есть

           start_time            end_time  duration  id
0 2020-01-01 00:00:00 2020-01-01 00:30:00        30   A
1 2020-01-01 00:30:00 2020-01-01 01:00:00        30   B
2 2020-01-01 01:00:00 2020-01-01 01:30:00        30   C
3 2020-01-01 01:30:00 2020-01-01 02:00:00        30   D
4 2020-01-04 05:00:00 2020-01-04 05:30:00        30   E
5 2020-01-04 05:30:00 2020-01-04 06:00:00        30   F
6 2020-01-04 06:00:00 2020-01-04 06:30:00        30   G
7 2020-01-04 06:30:00 2020-01-04 07:00:00        30   H
8 2020-01-04 20:30:00 2020-01-04 21:00:00        30   I

Что я пытаюсь вычислить sh в

           start_time            end_time  duration  id
0 2020-01-01 00:00:00 2020-01-01 02:00:00       120   A
4 2020-01-04 05:00:00 2020-01-04 07:00:00       120   E
8 2020-01-04 20:30:00 2020-01-04 21:00:00        30   I

Я искал варианты групп и слияний в pandas, но мне не удалось получить то, что я хочу.

Ответы [ 2 ]

2 голосов
/ 24 января 2020

Groupby.agg с Series.dt.date

 new_df =( df.groupby(df['end_time'].dt.date,as_index = False)
             .agg({'start_time':'first',
                    'end_time':'last',
                    'duration':'sum',
                    'id':'first'})
         )
print(new_df)

           start_time            end_time  duration id
0 2020-01-01 00:00:00 2020-01-01 02:00:00       120  A
1 2020-01-04 05:00:00 2020-01-04 07:00:00       120  E
0 голосов
/ 25 января 2020

Вы можете использовать DataFrame.shift для сравнения времени окончания со смещенным временем начала и установить для любых идентичных пар значение null:

df['flag'] = df['start_time'].shift(-1)
df.loc[df['end_time'] == df['flag'], 'flag'] = pd.NaT
print(df)                                                              
           start_time            end_time  duration id                flag
0 2020-01-01 00:00:00 2020-01-01 00:30:00        30  A                 NaT
1 2020-01-01 00:30:00 2020-01-01 01:00:00        30  B                 NaT
2 2020-01-01 01:00:00 2020-01-01 01:30:00        30  C                 NaT
3 2020-01-01 01:30:00 2020-01-01 02:00:00        30  D 2020-01-04 05:00:00
4 2020-01-04 05:00:00 2020-01-04 05:30:00        30  E                 NaT
5 2020-01-04 05:30:00 2020-01-04 06:00:00        30  F                 NaT
6 2020-01-04 06:00:00 2020-01-04 06:30:00        30  G                 NaT
7 2020-01-04 06:30:00 2020-01-04 07:00:00        30  H 2020-01-04 20:30:00
8 2020-01-04 20:30:00 2020-01-04 21:00:00        30  I                 NaT

Затем используйте DataFrame.bfill для заполнения этих нулей временем начала, которое нарушает ваше условие интервала. Вам нужно вручную установить нулевое значение для последнего значения.

df['flag'] = df['flag'].bfill().fillna(df['end_time'].iloc[-2])
print(df)                                                         
           start_time            end_time  duration id                flag
0 2020-01-01 00:00:00 2020-01-01 00:30:00        30  A 2020-01-04 05:00:00
1 2020-01-01 00:30:00 2020-01-01 01:00:00        30  B 2020-01-04 05:00:00
2 2020-01-01 01:00:00 2020-01-01 01:30:00        30  C 2020-01-04 05:00:00
3 2020-01-01 01:30:00 2020-01-01 02:00:00        30  D 2020-01-04 05:00:00
4 2020-01-04 05:00:00 2020-01-04 05:30:00        30  E 2020-01-04 20:30:00
5 2020-01-04 05:30:00 2020-01-04 06:00:00        30  F 2020-01-04 20:30:00
6 2020-01-04 06:00:00 2020-01-04 06:30:00        30  G 2020-01-04 20:30:00
7 2020-01-04 06:30:00 2020-01-04 07:00:00        30  H 2020-01-04 20:30:00
8 2020-01-04 20:30:00 2020-01-04 21:00:00        30  I 2020-01-04 07:00:00

Теперь сделайте так, как ansev предложил:

df = df.groupby('flag').agg({'start_time':'first','end_time':'last','duration':'sum','id':'first'}).reset_index(drop=True)
print(df)                                                                         
           start_time            end_time  duration id
0 2020-01-01 00:00:00 2020-01-01 02:00:00       120  A
1 2020-01-04 20:30:00 2020-01-04 21:00:00        30  I
2 2020-01-04 05:00:00 2020-01-04 07:00:00       120  E
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...