2016-12-18 46 views
4

我有一個熊貓數據幀,看起來像這樣:如何將此DataFrame中的信息表示爲時間序列?

   start_time    end_time user 
0 2016-12-17 03:10:07 2016-12-17 03:18:10 andrew 
1 2016-12-17 03:11:07 2016-12-17 03:15:07 eddie 
2 2016-12-17 03:12:08 2016-12-17 03:19:08 andrew 
3 2016-12-17 03:13:08 2016-12-17 03:14:06 eddie 
... 

每一行代表已提交到計算集羣的工作。 start_time是何時開始計劃作業運行,並且end_time是何時完成。

如何創建一個按時間索引的新DataFrame,它描述了每個用戶在給定時刻運行多少個作業?

+0

新數據框應該使用哪些時間值作爲索引,所有開始/結束時間的組合還是某些常規間隔? – FTP

+0

理想情況下,我將能夠做到這一點。 – ajwood

回答

1

這是一個相當有趣的問題。你基本上有兩個單獨的時間序列爲每個用戶。第一步是添加一個僅表示發生了事情的簡單列(列event)。策略是對數據進行循環,使得行是時間,列是用戶,事件是值。要創建一個完整的時間序列,我們需要對時間序列進行重新採樣(在這種情況下,我使用了1秒),並用0填充缺失值(因爲沒有發生任何事件,.min().fillna(0)用於填充數據幀爲NAS則零,我覺得你可以使用apply(lambda x:...)

df['event'] = 1 
df_starts = df.pivot('start_time', 'user', 'event').fillna(0).resample('1S').min().fillna(0) 
df_stops = df.pivot('end_time', 'user', 'event').fillna(0).resample('1S').min().fillna(0) 

接下來,我們創建兩個新的數據幀完整的索引快捷方式這一點,因爲該指數具有非重疊的部分,然後重新編制兩個數據使用新的幀index。

full_index = df_starts.index.union(df_stops.index) 

df_starts = df_starts.reindex(full_index, fill_value=0) 
df_stops = df_stops.reindex(full_index, fill_value=0) 

最後,從開始事件中減去停止事件將構建一個單一的數據框將所有事件。開始爲正1秒,止損爲1秒。使用​​可獲取每個用戶在任何給定時間的總運行進程。

df_change = df_starts - df_stops 
df_running = df_change.cumsum() 

這裏是df_running快速情節,x軸是自第一個事件的秒數。

enter image description here

1

這裏是一個溶液。它可能不是最優的,但它似乎工作得很好。當然,我已經生成了自己的數據,並假定用戶從零開始運行程序。

import pandas as pd 
import datetime as dt 

#Generate some data 
m = 50 
n = 2 * m 

start_time = [dt.datetime(2016, 12, 17, 3, np.random.randint(0, 59)) for n in range(n)] 

df = pd.DataFrame({'start_time': start_time, 
        'end_time': [date + dt.timedelta(0, np.random.randint(0, 3600)) for date in start_time], 
        'user': ['A', 'E'] * (m)}) 

#Doing the solution 
user_on = (df.ix[:, ['end_time', 'user']] 
      .rename(columns={'end_time':'time'}) 
      .assign(on_off=-1)) 
user_off = (df.ix[:, ['start_time', 'user']] 
       .rename(columns={'start_time':'time'}) 
       .assign(on_off=1)) 

df = pd.concat([user_on, user_off]).sort_values(by='time') 
df = df.groupby(['time', 'user']).sum() 
df = df.unstack().cumsum().fillna(method='ffill') 

下面是表格輸出的一個例子。

    on_off 
       user A E 
time   
2016-12-17 03:00:00 1 0 
2016-12-17 03:01:00 2 1 
2016-12-17 03:02:00 2 2 
2016-12-17 03:03:00 4 4 
2016-12-17 03:04:00 5 3 
2016-12-17 03:06:00 7 4 

比較倍這場耗時82MS做10,000個樣本,包括生成數據。

下圖顯示了隨時間變化的用戶程序總數(藍色和綠色)以及任何給定時間(紅色和紫色)​​運行程序的變化(開啓 - 關閉)。

Cusum vs Change in Programs run per User

注:在這種情況下,我假設一個用戶可以開始在給定的時間標記多個程序。這只是我產生測試日期的結果。

相關問題