【问题标题】:Grouping multiple datetime dataframe rows into a single one将多个日期时间数据框行分组为一个
【发布时间】:2020-05-10 23:57:51
【问题描述】:

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

我有什么

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

【问题讨论】:

  • 您的间隔是否只能在切点处重叠?如果是这样,一个简单的shift 可以让您分组。但如果可能有更复杂的重叠,那么逻辑就会变得更复杂。
  • 它们不重叠,它们总是相互跟随。我要研究一下班次

标签: python python-3.x pandas dataframe datetime


【解决方案1】:

Groupby.aggSeries.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

【讨论】:

  • 为了完美,我只是将 end_time 聚合函数更改为“last”而不是“first”。非常感谢先生:)
  • 我很乐意提供帮助:),请考虑接受答案
  • 我只是意识到,如果您有另一行同一天但很晚的数据,它会与另一行(同一天关闭)合并。我已经更新了最初的帖子
【解决方案2】:

您可以使用DataFrame.shift 将结束时间与偏移的开始时间进行比较,并将任何相同的对设置为空:

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 用违反间隔条件的开始时间回填那些空值。您需要自己手动为最后一个值设置 null 值。

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-06-24
    • 1970-01-01
    • 2019-07-17
    • 1970-01-01
    • 1970-01-01
    • 2021-12-14
    • 2021-10-13
    相关资源
    最近更新 更多