将多个日期时间数据帧行分组为一个数据帧行

2024-05-14 05:56:13 发布

您现在位置:Python中文网/ 问答频道 /正文

我有一个带有日期时间间隔的数据帧。我试图把它们压缩成单个项目。 我有每个事件的开始和结束时间以及相应的持续时间

我所拥有的

           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

我想把它压成什么

           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中寻找群组和合并选项,但我没有找到我想要的


Tags: 数据项目idpandas间隔time选项时间
2条回答

^{}^{}

 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

您可以使用^{}将结束时间与移位的开始时间进行比较,并将任何相同的对设置为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

然后使用^{}以违反间隔条件的开始时间回填这些空值。您需要为最后一个值手动设置空值

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

相关问题 更多 >