2017-08-14 23 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

謝謝!我將很快嘗試這個解決方案。一旦我嘗試過,會更新。 –