2017-08-14 75 views
1

我使用熊猫数据框以下:有效的方式来确定总时间考虑重叠情况考虑在内

我试图找到以确定船舶在特定泊位花在考虑到总时间的最佳方法在访问期间重叠。 这里是数据的样子:

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,而第三艘船在第一艘船之前出现,但是一直停留到第一艘船离开后这里的时间应该是=(从第一船的第三船开始),然后我们移动到下一个,因为那里没有重叠,并且简单地在泊位上花费的总时间加上[4的4 - ] 1,并继续这一直到最后产生这样的事情:

BERTH HOURS WORKED 
    01 7.750 
    02 10.275 
    03 5.585 
    08 31.980 
+0

你能告诉我们你的”到目前为止尝试过吗?我将首先建立一个时间间隔列表,当您处理新的时间间隔检查以查看它是否部分(或完全)落在您现有时间间隔内时,如果是,请根据需要修改现有时间间隔。 – larsks

+0

截至目前为止,我只尝试了一些if语句的循环,但它似乎没有捕获所有的情况。但是我明白你在说什么,我会尝试DYZ刚刚给出的解决方案。谢谢! –

回答

1

这是一个泊位的解决方案。我希望你能把它扩展到多个泊位。

拆分数据帧为抵港及离港:

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() 

确定停泊时间为空的时间段。然后计算每个“繁忙时段”的序号。

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_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_data['max'] - busy_data['min']).sum() 
#Timedelta('3 days 03:39:00') 
+0

谢谢!我将很快尝试这个解决方案。一旦我尝试过,会更新。 –