【问题标题】:I want to iterate over a loop and calculate total time till the condition lasts else total time till the condition doesn't last in python我想迭代一个循环并计算总时间直到条件持续否则总时间直到条件在python中不持续
【发布时间】:2020-07-28 11:12:06
【问题描述】:
 I have this kind of data:(given below):

[![This is my sample data][1]][1]

  
    RegistrationNo  EventType   StartDateTime        EndDateTime            Duration(inMins)
0   MH-04-**-****   Stop        2020-07-13 16:46:00  2020-07-14 04:53:00    727.0
1   MH-04-**-****   Transit     2020-07-14 04:53:00  2020-07-14 06:28:00    95.0
2   MH-04-**-****   Stop        2020-07-14 06:28:00  2020-07-14 06:52:00    24.0
3   MH-04-**-****   Transit     2020-07-14 06:52:00  2020-07-14 07:03:00    11.0
4   MH-04-**-****   Stop        2020-07-14 07:03:00  2020-07-14 07:58:00    55.0
5   MH-04-**-****   Transit     2020-07-14 07:58:00  2020-07-14 10:26:00    148.0
6   MH-04-**-****   Stop        2020-07-14 10:26:00  2020-07-14 10:55:00    29.0
7   MH-04-**-****   Transit     2020-07-14 10:55:00  2020-07-14 11:15:00    20.0
8   MH-04-**-****   Stop        2020-07-14 11:15:00  2020-07-14 11:59:00    44.0
9   MH-04-**-****   Transit     2020-07-14 11:59:00  2020-07-14 12:03:00    4.0
10  MH-04-**-****   Stop        2020-07-14 12:03:00  2020-07-14 16:18:00    255.0  
11  MH-04-**-****   Transit     2020-07-14 16:18:00  2020-07-14 16:19:00    1.0
12  MH-04-**-****   Stop        2020-07-14 16:19:00  2020-07-14 16:39:00    20.0
13  MH-04-**-****   Transit     2020-07-14 16:39:00  2020-07-14 18:20:00    101.0 
14  MH-04-**-****   Stop        2020-07-14 18:20:00  2020-07-14 20:22:00    122.0 
15  MH-04-**-****   Transit     2020-07-14 20:22:00  2020-07-14 21:41:00    79.0
16  MH-04-**-****   Stop        2020-07-14 21:41:00  2020-07-15 05:52:00    491.0
17  MH-04-**-****   Transit     2020-07-15 05:52:00  2020-07-15 07:37:00    105.0
18  MH-04-**-****   Stop        2020-07-15 07:37:00  2020-07-16 05:17:00    1300.0
19  MH-04-**-****   Transit     2020-07-16 05:17:00  2020-07-16 06:23:00    66.0
20  MH-04-**-****   Stop        2020-07-16 06:23:00  2020-07-16 08:11:00    108.0
21  MH-04-**-****   Transit     2020-07-16 08:11:00  2020-07-16 08:13:00    2.0
22  MH-04-**-****   Stop        2020-07-16 08:14:00  2020-07-16 09:22:00    68.0
23  MH-04-**-****   Transit     2020-07-16 09:22:00  2020-07-16 09:28:00    6.0
24  MH-04-**-****   Stop        2020-07-16 09:28:00  2020-07-16 09:45:00    17.0

我想制作一个程序,我想在每 4 个小时的驾驶中检查一次休息时间,如果总休息时间不超过 1 小时,那么它连续驾驶了多少时间,忽略总时间在第一个 4 小时间隔内休息少于 60 分钟/1 小时。

一些细节点:

总共开车超过 4 小时且没有休息至少 1 小时。 1小时的休息时间可以分为15分钟的休息时间。

连续驾驶超过 4 小时的每小时将被计为 1 次。例如。如果车辆连续行驶 5 小时 2 分钟,则计数为 2(第 5 小时和第 6 小时的 2 分钟)

我尝试了很多东西,但无法涵盖所有​​条件。

请帮忙,现在你们只是希望!提前致谢!

【问题讨论】:

  • 只有一句话和一些问题。 1/ 你应该首先尝试自己解决它并表现出诚实的尝试。 2/您想考虑 4 小时的重叠时间段还是仅考虑连续时间段? 3/ 在示例中,每一行的开始时间等于前一行的结束时间。是一致的还是数据框中可能存在漏洞或重叠?
  • 1.我从昨天开始就在尝试,即使我问朋友但没有成功..即使我发现循环令人困惑,而且条件很多。 :( .. 并且数据是一致的,您可以看到事件正在发生变化,一旦事件发生变化,第二次开始。
  • 您仍然没有回答是否应该考虑重叠 4 小时的时间段(比如 6:00 -> 10:00 然后 6:05 ->10:05 等)或只考虑连续的时间段(6 :00 ->10:00 然后 10:00 ->14:00)。即使您的代码不起作用,它也可以帮助显示它(以及当前和预期的行为),因为其他人可以向您解释它为什么不起作用;-)
  • 你可以看到时间段已经是连续的..是的,你说得有道理..:) 让我添加一些!
  • @SergeBallesta 如果你说的是从(第二行值)04:53:00 到 08:53:00,然后是(下一个值)06:52:00 到 10:52:00那么是的..是的,我们需要考虑每一次过境。

标签: python python-3.x pandas python-2.7 data-analysis


【解决方案1】:

我想您想知道的是,在任何 5 小时内是否有超过 4 小时的驾驶时间。因为它将在少于 1 个休息小时的情况下定义任何 4 个驾驶小时。

这可以通过首先以 1 分钟的频率重新采样原始数据,然后在 5 小时的运输时间段上使用滚动和来获得。

在 Pandas 中它可以提供:

tmp = df.assign(Transit=(df['EventType'] == 'Transit')
                ).set_index('StartDateTime')['Transit'].append(
    pd.Series([df.iloc[-1]['EventType'] == 'Transit'],
              index=[df.iloc[-1]['EndDateTime']])
    ).resample('1T').ffill().iloc[:-1].rolling('5H').sum().astype('int32')

公式详解:

  • assign(Transit=(df['EventType'] == 'Transit') 以可总结的方式确定运输时间
  • set_index('StartDateTime')['Transit'] 使用日期时间索引来简化重采样,并且只考虑新的 Transit 列(True == 运输时间)
  • append(pd.Series([df.iloc[-1]['Transit']], index=[df.iloc[-1]['EndDateTime']]) 将系列延长到上一期结束
  • resample('1T').ffill().iloc[:-1] 以 1 分钟的间隔重新采样并删除最后一分钟(否则最后一分钟会太长 1 分钟)
  • rolling('5H').sum() 将每 5 小时的总行驶时间相加
  • astype('int32') sum() 在 int32 足够时给出 float64

您现在可以像tmp[tmp > 240] 一样简单地测试违规行为。使用您的示例,它会给出一个空系列。

为了识别不同的违规行为,我无法想象一种矢量化的方式,所以我会在tmp > 240:

infrac = []
last = None
for i in tmp[tmp > 240].index:
    if (last is None) or (i >= last + pd.Timedelta('1H')): # one hour delay
        infrac.append(i)
        last = i

但我无法测试太多,因为样本不包含任何违规行为...


没有抓住重点的原始答案:

我可以计算出每个 4 小时序列的总休息时间,其中至少包含一些中转时间。我假设数据框不包含 4 小时或更长时间的传输序列。这意味着在使用下面的代码之前,长的驾驶序列应该被识别为:

df[(df['EventType'] == 'Transit')&(df['Duration(inMins)'] >= 240.)]

使用显示数据示例,上述查询返回一个空数据框。

我使用rolling 来识别 4 小时的序列。因为它使用右端,所以我将它应用在EndDateTime 上。由于只需要计算 4 小时内的休息时间,因此我使用了自定义计算函数。

代码是:

def sum_stop(x):
    x = df.loc[x.index]
    start = x.iloc[-1]['EndDateTime']-pd.Timedelta('4H')
    x = x[x['EventType'] == 'Stop']
    stop = np.where(x['StartDateTime']>=start, x['Duration(inMins)'],
                    (x['EndDateTime']-start).dt.total_seconds()/60.)
    return np.sum(stop)

df['BreakInPrevious4H'] = df.rolling('4H', on='EndDateTime')['Duration(inMins)'].apply(sum_stop)

它给出:

   RegistrationNo EventType       StartDateTime         EndDateTime  Duration(inMins)  BreakPrevious4H
0   MH-04-**-****      Stop 2020-07-13 16:46:00 2020-07-14 04:53:00             727.0            240.0
1   MH-04-**-****   Transit 2020-07-14 04:53:00 2020-07-14 06:28:00              95.0            145.0
2   MH-04-**-****      Stop 2020-07-14 06:28:00 2020-07-14 06:52:00              24.0            145.0
3   MH-04-**-****   Transit 2020-07-14 06:52:00 2020-07-14 07:03:00              11.0            134.0
4   MH-04-**-****      Stop 2020-07-14 07:03:00 2020-07-14 07:58:00              55.0            134.0
5   MH-04-**-****   Transit 2020-07-14 07:58:00 2020-07-14 10:26:00             148.0             79.0
6   MH-04-**-****      Stop 2020-07-14 10:26:00 2020-07-14 10:55:00              29.0             84.0
7   MH-04-**-****   Transit 2020-07-14 10:55:00 2020-07-14 11:15:00              20.0             72.0
8   MH-04-**-****      Stop 2020-07-14 11:15:00 2020-07-14 11:59:00              44.0             73.0
9   MH-04-**-****   Transit 2020-07-14 11:59:00 2020-07-14 12:03:00               4.0             73.0
10  MH-04-**-****      Stop 2020-07-14 12:03:00 2020-07-14 16:18:00             255.0            240.0
11  MH-04-**-****   Transit 2020-07-14 16:18:00 2020-07-14 16:19:00               1.0            239.0
12  MH-04-**-****      Stop 2020-07-14 16:19:00 2020-07-14 16:39:00              20.0            239.0
13  MH-04-**-****   Transit 2020-07-14 16:39:00 2020-07-14 18:20:00             101.0            138.0
14  MH-04-**-****      Stop 2020-07-14 18:20:00 2020-07-14 20:22:00             122.0            139.0
15  MH-04-**-****   Transit 2020-07-14 20:22:00 2020-07-14 21:41:00              79.0            122.0
16  MH-04-**-****      Stop 2020-07-14 21:41:00 2020-07-15 05:52:00             491.0            240.0
17  MH-04-**-****   Transit 2020-07-15 05:52:00 2020-07-15 07:37:00             105.0            135.0
18  MH-04-**-****      Stop 2020-07-15 07:37:00 2020-07-16 05:17:00            1300.0            240.0
19  MH-04-**-****   Transit 2020-07-16 05:17:00 2020-07-16 06:23:00              66.0            174.0
20  MH-04-**-****      Stop 2020-07-16 06:23:00 2020-07-16 08:11:00             108.0            174.0
21  MH-04-**-****   Transit 2020-07-16 08:11:00 2020-07-16 08:13:00               2.0            172.0
22  MH-04-**-****      Stop 2020-07-16 08:14:00 2020-07-16 09:22:00              68.0            176.0
23  MH-04-**-****   Transit 2020-07-16 09:22:00 2020-07-16 09:28:00               6.0            176.0
24  MH-04-**-****      Stop 2020-07-16 09:28:00 2020-07-16 09:45:00              17.0            193.0

补充说明:在BreakPrevious4H 列中没有特别标明超过4 小时的停留时间,但实际持续时间在Duration(inMins) 中(第0、10、16 和18 行)。

【讨论】:

  • 1.这不是我需要的理想解决方案..我认为您没有正确理解。然后让我向您解释一下。 @SergeBallesta
  • 我需要每隔 4 小时检查一次(这意味着车辆正在运行)车辆是否需要至少 1 小时,即 60 分钟休息
  • 如果不是,即如果车辆行驶 4 小时或更长时间并且总休息时间(即停止事件)少于 60 分钟,那么在这 4 小时的运行后每小时(第 5 小时)将被视为 1 个实例(1 个违规),如果它再次运行 1 分钟到 60 分钟,那么它将再次被视为 1 个实例,并且 +1 将被添加到之前的实例中,这意味着到目前为止没有。实例数为 2 ...,这样该过程将继续。这样我只需要那个总数。例如它已经完成了,它完成的日期和时间是什么时候?就是这样! @SergeBallesta
  • 在哪里?我看不见?
  • @PriyankaS.Desai:我把新答案放在第一位,然后是原来的答案......
猜你喜欢
  • 1970-01-01
  • 2019-07-21
  • 1970-01-01
  • 2014-01-14
  • 1970-01-01
  • 1970-01-01
  • 2021-11-26
  • 1970-01-01
  • 2018-06-29
相关资源
最近更新 更多