如何解决使用熊猫在时间段内划分持续时间 开始基本框架超级慢的部分结果
对于我正在执行的研究,我需要知道将工作的“持续时间”划分为任意时间段(每小时,每天,每月等)。如果工作1在9:30开始并在12:30结束,那么我希望在这4个时段(9-10、10-11、11-12、12-13)中有30分钟,1小时, 1小时30分钟。
我可以完成这项工作,但是速度非常慢。具有约30000个工作的基本案例大约需要100秒,仅占总数的0.5%。
框架的构建如下:
开始
import pandas as pd
frequency = "1H"
df = pd.DataFrame(
[
{
"job" : 1,"start" : pd.to_datetime("2020-01-01 10:00:00"),"end" : pd.to_datetime("2020-01-01 11:33:00"),},{
"job" : 2,"end" : pd.to_datetime("2020-01-02 09:33:00"),}
]
)
base_frame = df.set_index("job",append = True).stack().reset_index(level=[1,2])
base_frame = base_frame.drop("level_2",axis = 1).rename(columns={0 : 'time'})
基本框架
基本框架基本上会创建一个id,并将“开始”和“结束”都放在同一列中。
|id | job | time | |---:|------:|:--------------------| | 0 | 1 | 2020-01-01 10:00:00 | | 0 | 1 | 2020-01-01 11:33:00 | | 1 | 2 | 2020-01-01 10:00:00 | | 1 | 2 | 2020-01-02 09:33:00 |
超级慢的部分
好的,这是真正的问题所在。对于每个组ID(也可能是作业ID),我需要重新采样,因此将“时间”列放入索引中。然后,我需要回填数据。最后,我计算每组的持续时间。
最后使用“ where”限制了周期的大小。
做这样的事情已经是一种进步,因为在groupby上使用for循环花费了两倍的时间。
def assignFunc(x):
x["duration"] = pd.Timedelta(0)
if len(x) >= 2:
x.iloc[0,x.columns.get_loc('duration')] = x.index[1] - x['time'].iloc[0]
x.iloc[1:,x.columns.get_loc('duration')] = x['time'].iloc[1:] - x.index[1:]
else:
x.iloc[0,x.columns.get_loc('duration')] = base_frame['time'].iloc[-1] - base_frame['time'].iloc[0]
return x["duration"]
frame = base_frame.groupby(base_frame.index).apply(lambda x: x.set_index('time',drop=False).resample(frequency).bfill().assign(duration=assignFunc))
frame["duration"] = frame.where(frame.duration <= pd.Timedelta(frequency),pd.Timedelta(frequency))["duration"]
print(frame.drop("time",axis=1))
结果
time
0 2020-01-01 10:00:00 1 0 days 01:00:00
2020-01-01 11:00:00 1 0 days 00:33:00
1 2020-01-01 10:00:00 2 0 days 01:00:00
2020-01-01 11:00:00 2 0 days 01:00:00
2020-01-01 12:00:00 2 0 days 01:00:00
2020-01-01 13:00:00 2 0 days 01:00:00
2020-01-01 14:00:00 2 0 days 01:00:00
2020-01-01 15:00:00 2 0 days 01:00:00
2020-01-01 16:00:00 2 0 days 01:00:00
....
您知道如何解决此问题吗?我的想法依赖于for循环(因为我需要重新采样每个循环),这会非常慢。
谢谢大家!
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。