【问题标题】:breaking down time intervals and assigning them to corresponding hours分解时间间隔并将它们分配给相应的时间
【发布时间】:2019-08-03 06:02:30
【问题描述】:

给定一个事件的开始时间和结束时间,我想指定它们所属的小时(开始时间)的相应持续时间:

例如,如果我有一个数据框:

event      start_time       end_time       
a            8:00             8:30               
b            8:49            10:22

在这种情况下,hour(start_time) = 8,与第一行一样被分配 30 分钟。 但是,如果 start_time 和 end_time 的小时数不像第二行那样相等, 那么我想将 start_time 和 end_time 拆分如下:

event      start_time       end_time        hour(start_time)      duration
a            8:00             8:30                8                 30
b            8:49            9:00                 8                 11
b            9:00            10:00                9                 60
b            10:00           10:22                10                22

在 pandas 中是否有一种简单的方法来实现这一点?

【问题讨论】:

  • Is there a straightforward way to accomplish this in pandas? - 我不认为,在熊猫中不存在此功能。那么你可以将你的循环解决方案添加到问题中吗?

标签: pandas timestamp


【解决方案1】:

为了轻松处理数据,将时间转换为日期时间,按差异重复行,并使用GroupBy.cumcountto_timedelta 为开始、结束和小时列添加或减去时间增量,最后一轮由Series.dt.floorSeries.dt.ceil 新日期时间:

print (df)
  event start_time end_time
0     a       8:00     8:30
1     b       8:49    10:22

df['s'] = pd.to_datetime(df['start_time'], format='%H:%M')
df['e'] = pd.to_datetime(df['end_time'], format='%H:%M')
df['hour'] = df['s'].dt.hour

df = df.loc[df.index.repeat(df['e'].dt.hour.sub(df['hour']).add(1))]

idx = df.index
m1 =  idx.duplicated()
m2 =  idx.duplicated(keep='last')

df = df.reset_index(drop=True)
s = df.groupby(idx).cumcount()
s1 = df.groupby(idx).cumcount(ascending=False)

df['hour'] = df['hour'].add(s)
df.loc[m1, 's'] += pd.to_timedelta(s, unit='H')
df.loc[m1, 's'] = df.loc[m1, 's'].dt.floor('H')

df.loc[m2, 'e'] -= pd.to_timedelta(s1, unit='H')
df.loc[m2, 'e'] = df.loc[m2, 'e'].dt.ceil('H')

df['duration'] = df['e'].sub(df['s']).dt.total_seconds().div(60).astype(int)
df['start_time'] = df.pop('s').dt.strftime('%H:%M')
df['end_time'] = df.pop('e').dt.strftime('%H:%M')

print (df)
  event start_time end_time  hour  duration
0     a      08:00    08:30     8        30
1     b      08:49    09:00     8        11
2     b      09:00    10:00     9        60
3     b      10:00    10:22    10        22

【讨论】:

  • 谢谢,'repeat'、'ceil' 和 'floor' 对我来说都是新的。同样在您回复之前,我仍在努力使用 groupby-apply 解决问题。非常感谢!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2022-10-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-10-27
  • 2020-08-09
  • 2022-01-20
相关资源
最近更新 更多