看过来
《pandas 教程》 持续更新中,提供建议、纠错、催更等加作者微信: gairuo123(备注:pandas教程)和关注公众号「盖若」ID: gairuo。跟作者学习,请进入 Python学习课程。欢迎关注作者出版的书籍:《深入浅出Pandas》 和 《Python之光》。
本例中,有一些时间段数据,需要将这些时间段里的时间以小时为分组,将24个小时段中每个小时所占用的秒数计算出来。
数据集如下,包含了开始时间和结束时间:
'''
start_time,end_time
2/2/2021 07:24:15,2/2/2021 08:54:41
2/3/2021 11:00:05,2/3/2021 15:10:37
2/1/2021 10:40:34,2/1/2021 14:43:50
2/4/2021 10:37:37,2/4/2021 11:19:17
2/3/2021 20:37:51,2/4/2021 02:37:52
2/3/2021 21:37:52,2/3/2021 22:08:39
'''
以第一条数据为例,它所在两个小时,7点段占用24分钟15秒,8点段54分钟41秒。其他数据同理进行解析计算,最后按小时段合并,最终计算出各个小时段的用时。
处理思路和流程如下(可对照代码阅读):
根据以上思路,代码实现如下:
import pandas as pd
# 读取剪贴板,用逗号分隔,解析两个字段为时间类型
df = pd.read_clipboard(sep=',', parse_dates=[0,1])
# 查看类型
df.dtypes
'''
start_time datetime64[ns]
end_time datetime64[ns]
dtype: object
'''
# 函数,将开始时间和结束时间解析为每个小时的时长(秒)
def duration_by_hour(start, end):
p = pd.period_range(pd.Period(start, freq='s'), pd.Period(end, freq='s'))
pr = {h:pd.to_timedelta(t[-1]-t[0]).seconds for h,t in p.groupby(p.hour).items()}
return pr
# 将每行数据应用函数,解析出每个小时对应的秒数
s = df.apply(lambda r: duration_by_hour(r.start_time, r.end_time), axis=1)
s
'''
0 {7: 2144, 8: 3281}
1 {11: 3594, 12: 3599, 13: 3599, 14: 3599, 15: 637}
2 {10: 1165, 11: 3599, 12: 3599, 13: 3599, 14: 2...
3 {10: 1342, 11: 1157}
4 {0: 3599, 1: 3599, 2: 2272, 20: 1328, 21: 3599...
5 {21: 1327, 22: 519}
dtype: object
'''
# 按小时合并秒数
final = {}
for d in s.to_list():
for k in d.keys():
final[k] = final.get(k,0) + d[k]
final
'''
{7: 2144,
8: 3281,
11: 8350,
12: 7198,
13: 7198,
14: 6229,
15: 637,
10: 2507,
0: 3599,
1: 3599,
2: 2272,
20: 1328,
21: 4926,
22: 4118,
23: 3599}
'''
# 可视化,单位转换为分钟
(pd.Series(final).sort_index()/60).plot.bar()
# 见下图
更加简化的思路:
def func(ser):
s = pd.date_range(ser.start_time, ser.end_time, freq='s')
return pd.Series(s).groupby(s.hour).count()-1
df.apply(func, axis=1).sum().astype(int)
这样就完成了需求。
(完)
更新时间:2024-08-18 15:40:48 标签:pandas python 时间 时长