在考虑重叠的情况下确定总时间的有效方法
Efficient way to determine total time taking overlap into account
我正在为以下内容使用 pandas 数据框:
我正在尝试找到确定船舶在特定泊位花费的总时间的最佳方法,同时考虑访问持续时间的重叠。
数据如下所示:
IN OUT BERTH
2015-01-14 13:57:00 2015-01-15 17:15:00 01
2015-01-14 14:30:00 2015-01-15 02:50:00 01
2015-01-14 14:30:00 2015-01-16 06:10:00 01
2015-01-25 02:15:00 2015-01-26 13:41:00 01
我真正想要的是找出特定泊位的总使用时间。所以查看数据有重叠,所以我不能简单地为每条记录添加时间。
查看上面的数据我们可以看到,第二艘船的时间完全在第一艘船内,所以记录的时间为0,第三艘船在第一艘船之前到达,但一直停留到第一艘船离开后所以这里的时间将是 =(第 3 艘船外 - 第 1 艘船内)然后我们将移动到下一艘,因为那里没有重叠,只需将 [out of 4 - in of 4] 添加到花费的总时间泊位 1,并继续这个直到最后产生这样的东西:
BERTH HOURS WORKED
01 7.750
02 10.275
03 5.585
08 31.980
这是一个泊位的解决方案。希望你们可以扩展到多个泊位。
将数据帧拆分为到达和离开:
dfIN = df[['IN']]
dfOUT = df[['OUT']]
dfIN['direction'] = 1
dfOUT['diretcion'] = -1
截至目前,IN 和 OUT 只是时间戳:
dfIN.columns = ('TS', 'direction')
dfOUT.columns = ('TS', 'direction')
将这两部分合并成一个高排序的流量数据帧:
traffic = pd.concat([dfIN, dfOUT]).sort_values('TS')
# TS direction
#0 2015-01-14 13:57:00 1
#1 2015-01-14 14:30:00 1
#2 2015-01-14 14:30:00 1
#1 2015-01-15 02:50:00 -1
#0 2015-01-15 17:15:00 -1
#2 2015-01-16 06:10:00 -1
#3 2015-01-25 02:15:00 1
#3 2015-01-26 13:41:00 -1
计算停靠泊位的船只数量,因为它们到达和离开:
traffic['ships'] = traffic['direction'].cumsum()
确定泊位空置的时间段。然后计算每个"busy period."
的序号
traffic['empty'] = (traffic['ships'] == 0).shift().fillna(0).astype(int)
traffic['busy_id'] = traffic['empty'].cumsum()
# TS direction ships empty busy_id
#0 2015-01-14 13:57:00 1 1 0 0
#1 2015-01-14 14:30:00 1 2 0 0
#2 2015-01-14 14:30:00 1 3 0 0
#1 2015-01-15 02:50:00 -1 2 0 0
#0 2015-01-15 17:15:00 -1 1 0 0
#2 2015-01-16 06:10:00 -1 0 0 0
#3 2015-01-25 02:15:00 1 1 1 1
#3 2015-01-26 13:41:00 -1 0 0 1
计算每个"busy period"的开始和结束:
busy_data = traffic.groupby('busy_id')['TS'].agg([min, max])
# min max
#busy_id
#0 2015-01-14 13:57:00 2015-01-16 06:10:00
#1 2015-01-25 02:15:00 2015-01-26 13:41:00
计算所有"busy periods":
的总长度
(busy_data['max'] - busy_data['min']).sum()
#Timedelta('3 days 03:39:00')
我正在为以下内容使用 pandas 数据框:
我正在尝试找到确定船舶在特定泊位花费的总时间的最佳方法,同时考虑访问持续时间的重叠。 数据如下所示:
IN OUT BERTH
2015-01-14 13:57:00 2015-01-15 17:15:00 01
2015-01-14 14:30:00 2015-01-15 02:50:00 01
2015-01-14 14:30:00 2015-01-16 06:10:00 01
2015-01-25 02:15:00 2015-01-26 13:41:00 01
我真正想要的是找出特定泊位的总使用时间。所以查看数据有重叠,所以我不能简单地为每条记录添加时间。
查看上面的数据我们可以看到,第二艘船的时间完全在第一艘船内,所以记录的时间为0,第三艘船在第一艘船之前到达,但一直停留到第一艘船离开后所以这里的时间将是 =(第 3 艘船外 - 第 1 艘船内)然后我们将移动到下一艘,因为那里没有重叠,只需将 [out of 4 - in of 4] 添加到花费的总时间泊位 1,并继续这个直到最后产生这样的东西:
BERTH HOURS WORKED
01 7.750
02 10.275
03 5.585
08 31.980
这是一个泊位的解决方案。希望你们可以扩展到多个泊位。
将数据帧拆分为到达和离开:
dfIN = df[['IN']]
dfOUT = df[['OUT']]
dfIN['direction'] = 1
dfOUT['diretcion'] = -1
截至目前,IN 和 OUT 只是时间戳:
dfIN.columns = ('TS', 'direction')
dfOUT.columns = ('TS', 'direction')
将这两部分合并成一个高排序的流量数据帧:
traffic = pd.concat([dfIN, dfOUT]).sort_values('TS')
# TS direction
#0 2015-01-14 13:57:00 1
#1 2015-01-14 14:30:00 1
#2 2015-01-14 14:30:00 1
#1 2015-01-15 02:50:00 -1
#0 2015-01-15 17:15:00 -1
#2 2015-01-16 06:10:00 -1
#3 2015-01-25 02:15:00 1
#3 2015-01-26 13:41:00 -1
计算停靠泊位的船只数量,因为它们到达和离开:
traffic['ships'] = traffic['direction'].cumsum()
确定泊位空置的时间段。然后计算每个"busy period."
的序号traffic['empty'] = (traffic['ships'] == 0).shift().fillna(0).astype(int)
traffic['busy_id'] = traffic['empty'].cumsum()
# TS direction ships empty busy_id
#0 2015-01-14 13:57:00 1 1 0 0
#1 2015-01-14 14:30:00 1 2 0 0
#2 2015-01-14 14:30:00 1 3 0 0
#1 2015-01-15 02:50:00 -1 2 0 0
#0 2015-01-15 17:15:00 -1 1 0 0
#2 2015-01-16 06:10:00 -1 0 0 0
#3 2015-01-25 02:15:00 1 1 1 1
#3 2015-01-26 13:41:00 -1 0 0 1
计算每个"busy period"的开始和结束:
busy_data = traffic.groupby('busy_id')['TS'].agg([min, max])
# min max
#busy_id
#0 2015-01-14 13:57:00 2015-01-16 06:10:00
#1 2015-01-25 02:15:00 2015-01-26 13:41:00
计算所有"busy periods":
的总长度(busy_data['max'] - busy_data['min']).sum()
#Timedelta('3 days 03:39:00')