2013-12-10 45 views
3

我正在收集特定用例的交通信息,每10分鐘(但不準確)流量計數器的時間戳值,如:從時間戳流量計數器創建彙總統計信息

11:45 100 
11:56 110 
12:05 120 
12:18 130 
... 

這是我的數據,我不能提高一點。

我想從這個輸入中產生某種每小時/每日統計數據,你能提出一些現成的函數或python中的算法嗎?

我正在考慮將時間戳計數器分爲幾小時,並將小時的第一個時間戳與最後一個小時的時間戳進行比較,並將差異顯示爲給定小時內的交通流量,但因爲這可能不會與小時例如以上述數據,它始於120 @ 12:05),它可能會完全關閉,並且按比例包含以前的數據(例如((120-110)/ 9)* 5)也會很好。但我不想重新發明輪子。

- 更新 -

基於下面的建議,我已經調查大熊貓產生下面的代碼。爲了澄清上述書面背景,時間戳值是二級的,並在一分鐘內不規則地分佈(例如11:45:03,11:56:34等)。因此,下面的代碼將輸入,重新索引到第二級,執行線性插值(假設流量均勻分佈在測量點之間),削減第一個和最後一個小數分鐘(以便如果第一個數據點在11:45 :03,它不會由於前3秒的缺失而失真)並將二級數據重新採樣到分級。目前這種方式正如預期的那樣工作,但速度非常緩慢,我想是由於二級插值,因爲數據跨越了幾個月的時間。任何想法如何進一步改善或加快代碼?

import datetime 
import pandas as pd 
import numpy as np 
import math 

COLUMNS = ['date', 'lan_in', 'inet_in', 'lan_out', 'inet_out'] 

ts_converter = lambda x: datetime.datetime.fromtimestamp(int(x)) 
td = pd.read_table("traffic_log", 
        names = COLUMNS, 
        delim_whitespace = True, 
        header = None, 
        converters = { 'date' : ts_converter }).set_index('date') 

# reindex to second-level data 
td = td.reindex(pd.date_range(min(td.index), max(td.index), freq="s")) 
# linear interpolation to fill data for all seconds 
td = td.apply(pd.Series.interpolate) 
# cut first and last fractional minute data 
td = td[pd.Timestamp(long(math.ceil(td.index.min().value/(1e9*60))*1e9*60)): 
     pd.Timestamp(long(math.floor(td.index.max().value/(1e9*60))*1e9*60))] 
# resample to minute-level taking the minimum value for each minute 
td = td.resample("t", how="min") 
# change absolute values to differences 
td = td.apply(pd.Series.diff) 
# create daily statistics in gigabytes 
ds = td.resample("d", how="sum").apply(lambda v: v/1024/1024/1024) 
# create speed columns 
for i in COLUMNS[1:]: 
    td[i+'_speed'] = td[i]/60/1024 
+1

使用http://pandas.pydata.org/ – YXD

回答

1

如果我理解你的問題正確,也許這將有助於:

df = pd.DataFrame([ ['11:45', 100 ], ['11:56', 110], ['12:05', 120], ['12:18', 130]], 
        columns=['tick', 'val']) 
df.tick = df.tick.map (pd.Timestamp) 

所以df看起來是這樣的:

    tick val 
0 2013-12-10 11:45:00 100 
1 2013-12-10 11:56:00 110 
2 2013-12-10 12:05:00 120 
3 2013-12-10 12:18:00 130 

現在你可以計算每個區間的長度,並找到小時平均值:

df[ 'period' ] = df.tick - df.tick.shift(1) 
df.period = df.period.div(np.timedelta64('1', 'h')) 
df[ 'chval' ] = df.val - df.val.shift(1) 
df[ 'havg' ] = df.chval/df.period 

輸出:

    tick val period chval  havg 
0 2013-12-10 11:45:00 100  NaN NaN  NaN 
1 2013-12-10 11:56:00 110 0.1833  10 54.5455 
2 2013-12-10 12:05:00 120 0.1500  10 66.6667 
3 2013-12-10 12:18:00 130 0.2167  10 46.1538 

採取帳戶,某些時期跨越了一個多小時,我認爲一個解決辦法是改變頻率來分,落後填充所有NaN值,然後用平均值計算每小時重新取樣:

df = df.set_index('tick').asfreq(freq='T', method='bfill') 
df = df.shift(-1).resample('h', how='mean') 

輸出:

      val period chval  havg 
2013-12-10 11:00:00 112.6667 0.1744  10 57.7778 
2013-12-10 12:00:00 127.2222 0.1981  10 51.8519 

現在我覺得havg值coorect,如

(10 + 10 * 4/9)/15 * 60 = 57.7778 
(  10 * 5/9 + 10)/18 * 60 = 51.8519 
+0

謝謝,這看起來不錯,但我也需要流量的總和除了速度,即我要改變這個數據集具有正規分鐘級別的數據集è 。g在12:00點,值爲110 + 10 * 4/9(假設測量間隔內的速度均勻分佈),我該怎麼做? – abali

+1

@abali即插值,請參見[this](http://pandas.pydata.org/pandas-docs/stable/generated/pandas.Series.interpolate.html#pandas.Series.interpolate) –

+0

謝謝,這個工作正常它很慢 - 我已經編輯了更新的問題,歡迎任何進一步的建議。 – abali