2016-11-07 42 views
3

我有一個接受時間序列數據的python服務器。現在我需要計算最後一分鐘的平均流量,輸出像90個樣本/分鐘。我目前正在使用一個Python列表來保存所有時間戳,並使用一種非常糟糕的方式(在我看來)來計算這個。代碼大致是這樣的:如何計算最後一分鐘的運行平均流量

class TrafficCalculator(object): 
    timestamps = [] 

    def run(): 
     while True: 
      # this gets one record of traffic 
      data = self.accept_data() 
      # get record's timestamp 
      timestamp = data.timestamp 
      # add to list 
      self.timestamps.append(timestamp) 
      # get the time one minute ago 
      minute_ago = timestamp - datetime.timedelta(minutes=1) 
      # find out the first index of the timestamp in the past that's within 1 minute 
      for i, t in enumerate(self.timestamp): 
       if t > minute_ago: 
        break 
      # see how many records are within last minute 
      result = len(self.timestamp[i:]) 
      # throw away the earlier data 
      self.timestamp = self.timestamp[i:] 

正如你所看到的,我必須爲每個記錄做到這一點,如果我的流量獲取激烈,性能更是苦不堪言。

有更好的數據結構或算法,我可以使用這個更高性能嗎?更進一步,如何編寫測試來驗證我的算法?謝謝!

+1

爲什麼不使用類似[熊貓](HTTP: //pandas.pydata.org/pandas-docs/stable/timeseries.html)? – Bahrom

+0

您是否嘗試過在每次打開函數時都勾選int,並且每分鐘清除一次?爲了測試你的課程,你所要做的就是創建一個腳本,用隨機數據破壞self.accept_data()。 –

回答

4

使用隊列來保存<traffic, timestamp>對。這裏timestamp是它被推入隊列的時間(從服務器到達)。跟蹤隊列流量的sum。當新流量到達並且其時間戳和隊列的前端元素的時間戳之間的差異超過1分鐘時,從隊列中彈出。從總和中減去popp流量值。將新流量推入隊列並添加到總和中。

這樣,您的隊列就像一個窗口框架一直持續1分鐘的流量。而且您正在追蹤總和並知道隊列大小,因此您可以計算平均值。

空間複雜度爲O(maximum traffic can be arrived within 1 minute)。時間複雜度是O(1)隨時獲得平均值。

這是一個非常傳統的算法在恆定時間複雜度上查詢任何正在運行的數據流。

注意:不幸的是我不知道Python。否則,我會把實施。

+1

謝謝,你不知道python,但我知道編程,所以它沒關係。我有點不舒服,因爲它很明顯。 –

+0

不客氣。有時我們會錯過非常明顯的事情 –

1

你可能是能夠與這樣的實現的:

  • 定義向量(或列表)的長度90的data
  • 有一個指針p=0
  • (樣品/分鐘)有一個sum變量(未初始化)

用90個第一個樣本填充向量;計算總和並存入變量sum

然後:

  • 。減去data[p]sum(刪除從總和最舊的樣本)
  • 讀下一個樣品,並把它在載體中在位置p (從而擦除所述最舊的數據);
  • 增加新的data[p]sum(當前總和)
  • 增量指針p減1;如果p> = 90,則p = 0再次 (p指向最老的可用數據)
  • 電流平均值是sum/90