看过来
《pandas 教程》 持续更新中,提供建议、纠错、催更等加作者微信: gr99123(备注:pandas教程)和关注公众号「盖若」ID: gairuo。跟作者学习,请进入 Python学习课程。欢迎关注作者出版的书籍:《深入浅出Pandas》 和 《Python之光》。
本例,我们对一个时间序列进行解析,得到这个时间所在的区间分别在不同的周中有多少个小时,这对时序问题来说非常实用,方便我们对工作按周进行分析。来看看 pandas 是如何应对这种问题的。
我们的生产数据如下:
import pandas as pd
import io
data = '''
pid,start,end
A1,2024-10-12 09:30:00,2024-10-13 09:30:00
A2,2024-10-15 19:30:00,2024-10-24 09:30:00
B1,2024-10-01 12:00:00,2024-10-24 09:30:00
B2,2024-10-20 19:30:00,2024-10-07 09:30:00
'''
df = pd.read_csv(io.StringIO(data))
df = df.astype({'start': 'datetime64[ns]', 'start': 'datetime64[ns]'})
df
'''
pid start end
0 A1 2024-10-12 09:30:00 2024-10-13 09:30:00
1 A2 2024-10-15 19:30:00 2024-10-24 09:30:00
2 B1 2024-10-01 12:00:00 2024-10-24 09:30:00
3 B2 2024-10-20 19:30:00 2024-10-07 09:30:00
'''
pid 是商品的 ID,对应的两列分别是这个商品的生产开始时间和完成生产时间。我们的需求是,要分析每个周分别用在生产此商品的时间是多少小时。
得到的结果如下:
week 40 41 42 43
pid
A1 0.0 24.0 0.0 0.0
A2 0.0 0.0 124.0 81.5
B1 131.5 167.5 167.5 81.5
列头的数字为当年的周数。
我们可以利用每行数据中的开始时间和结束时间构造一个时间序列,然后对商品和这个时间序列的周进行分组,聚合每个组的总时间。
再对这个堆叠数据解除堆叠,并转换为小时数就得到了最终的结果。
最终的代码如下:
(
df.set_index('pid')
.apply(lambda x: pd.date_range(x.start, x.end, freq='30min'), axis=1)
.explode()
.pipe(lambda x: x.groupby([x.index, x.dt.isocalendar().week]))
.apply(lambda x: x.diff().sum())
.dt.total_seconds().div(3600)
.unstack()
.fillna(0)
)
'''
week 40 41 42 43
pid
A1 0.0 24.0 0.0 0.0
A2 0.0 0.0 124.0 81.5
B1 131.5 167.5 167.5 81.5
'''
这样就得到了最终的结果。
(完)
更新时间:2024-12-12 15:31:39 标签:pandas python 时间