【问题标题】:How to subdivide a datetime interval into multiple (smaller) ones?如何将日期时间间隔细分为多个(较小的)?
【发布时间】:2021-07-27 17:32:42
【问题描述】:

假设我们有一个名为“chosen_data”的数据框,其中包含开始和结束日期以及我们可以在其中执行任务的可用槽的持续时间(我将提供一个示例,以便您可以根据需要复制它)。让我们将任务持续时间固定为 x = 24h,如果我的第一个可用插槽的持续时间是 100 小时,我想将其细分为 100-24=76 个部分,其中每个部分的持续时间等于“x”。我想将这些部分存储到一个新的数据框(称为结果)中,其中包含每个细分的开始和结束日期。

实际的脚本可以完成这项工作,但是当我将它应用于更大的数据集时,它需要永远运行,我只需要替换 for 循环:

import pandas as pd
import numpy as np
data = [['3/6/1999 5:00','3/8/1999 0:00',43],['3/8/1999 22:00','3/12/1999 19:00',93],['3/12/1999  22:00','3/21/1999 20:00',214],['3/22/1999 19:00','3/26/1999 3:00',80]]
chosen_data = pd.DataFrame(data, columns = ['Start Date', 'End Date', 'Duration [Hours]'])
chosen_data[['Start Date','End Date']] = chosen_data[['Start Date','End Date']].apply(pd.to_datetime)

result = pd.DataFrame(columns=['Start Date','End Date', 'Duration [Hours]'])
x = 24 # Task duration(normaly it's a user input variable)
for i in chosen_data.index : 
    fenetre = chosen_data.copy()
    num_subdiv = fenetre['Duration [Hours]'].loc[i] - x    
    for j in range(int(num_subdiv)) :        
        fenetre['Start Date'].loc[i] = fenetre['Start Date'].loc[i] + pd.to_timedelta(1, unit ='h')
        #fenetre['Start Date'].loc[i] = fenetre['Start Date'].loc[i] + pd.to_timedelta(j, unit ='h')
        fenetre['End Date'].loc[i] = fenetre['Start Date'].loc[i] + pd.to_timedelta(x , unit ='h')
        #fenetre['End Date'].loc[i] = fenetre['End Date'].loc[i] + pd.to_timedelta(j - substract ,   unit ='h')      
        result = result.append(fenetre.loc[i] , ignore_index= True)
        
result['Duration [Hours]'] = (result['End Date'] - result['Start Date']) / pd.to_timedelta(1, unit = 'h')

我正在寻找一种更好的方法来实现这个目的,这是所需的输出

【问题讨论】:

  • result['Duration [Hours]'] = pd.to_timedelta(x , unit ='h') 最后做同样的事情
  • 确实如此,或者只是结果['duration'] = x。但是,我使用该公式来检查我的输出是否正确。它帮助我调试
  • 你知道这行代码在微秒内执行吗?它在for循环之外,所以这不是我的执行时间问题的根源,也不是这篇文章的答案......

标签: python pandas datetime for-loop


【解决方案1】:

使用Explode value to multiple rows

x = 24
chosen_data['values'] = (chosen_data['Duration [Hours]'] - x).apply(lambda a: list(range(1, 1 + a)))
result: pd.DataFrame = pd.DataFrame(chosen_data['values'].tolist(), index=chosen_data['Start Date']) \
    .stack().reset_index()[["Start Date", 0]]

result.columns = ["Start Date", "ToAdd"]
result['Start Date'] = result['Start Date'] + pd.to_timedelta(result['ToAdd'], unit='h')
result['End Date'] = result['Start Date'] + pd.to_timedelta(x, unit='h')
result['Duration'] = x

打印choosen_data 给出,然后为values 列的每个值爆炸

Start Date End Date Duration [Hours] values
0 1999-03-06 05:00:00 1999-03-08 00:00:00 27 [1, 2, 3]
1 1999-03-08 22:00:00 1999-03-12 19:00:00 26 [1, 2]
2 1999-03-12 22:00:00 1999-03-21 20:00:00 28 [1, 2, 3, 4]
3 1999-03-22 19:00:00 1999-03-26 03:00:00 26 [1, 2]

【讨论】:

  • 现在这很顺利,我的男人!谢谢哥们,我从来没有遇到过 'Stack()' 和 'tolist()' 方法,所以这个解决方案启发了我并且对我的项目的连续性很有用。
猜你喜欢
  • 2021-10-13
  • 2012-01-01
  • 2019-07-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-10-24
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多