2013-04-03 119 views
2

我做了一個代碼,它可以在下面生成隨機數字,我將它們保存在如下所示的csv中,我試圖通過函數來​​學習該組。我想例如通過時間戳來完成這些組的總和或平均值。我是Python新手,雖然我找不到任何地方。 Ulitmately我想這樣做,但1分鐘或5分鐘(每5分鐘從00:00:00開始,沒有足夠的數據在我的例子下面,但會做一些像13:35:00至13:40:00和下一個13:40:00包括到13:45:00排除在外等),我想我可以計算出1分鐘從時間戳中提取分鐘部分,但5分鐘似乎很複雜。不要求複製代碼副本,但我不知道從哪裏開始說實話。按頻率對數據進行分組

 
Level Timestamp 
99 03/04/2013 13:37:20 
98 03/04/2013 13:37:20 
98 03/04/2013 13:37:20 
99 03/04/2013 13:37:20 
105 03/04/2013 13:37:20 
104 03/04/2013 13:37:20 
102 03/04/2013 13:37:21 
102 03/04/2013 13:37:21 
103 03/04/2013 13:37:22 
82 03/04/2013 13:37:23 
83 03/04/2013 13:37:23 
82 03/04/2013 13:37:23 
83 03/04/2013 13:37:23 
54 03/04/2013 13:37:24 
55 03/04/2013 13:37:24 
54 03/04/2013 13:37:24 
55 03/04/2013 13:37:24 
56 03/04/2013 13:37:25 
57 03/04/2013 13:37:25 
+0

只是狡辯 - 它看起來像它的製表符分隔,而不是逗號分隔(CSV表示逗號分隔值)。 – Hannele

+0

否則,我對你試圖完成的事情感到有點困惑 - 你能舉一個例子來說明結果數據集是什麼樣的嗎? – Hannele

+0

即時通訊只想通過時間戳得到一行,不管這是總計還是平均值 – matel

回答

3

它可以用itertools http://docs.python.org/2/library/itertools.html#itertools.groupby

做,但要小心:

它產生中斷或新組每一次的關鍵 函數的值發生變化(這就是爲什麼它通常是必須使用相同的按鍵功能對 數據進行排序)。

使用示例:

如果您的數據已經處理爲級別的列表,時間戳對。

data = [(99, '03/04/2013 13:37:20'), (98, '03/04/2013 13:37:20'), ...] 

你想通過AVG的數據組5分鐘間隔

data.sort(key=lambda i: i[1]) # sort with timestamp 
results = [] 

def keyfunc(timestamp, interval = 5*60): 
    # defined a key function. 
    # 1. parse the datetime string to datetime object 
    # 2. count the time delta (seconds) 
    # 3. divided the time delta with interval, which is (6*60) here 
    xt = datetime(2013, 4,3) 
    dt = datetime.strptime(timestamp, '%d/%m/%Y %H:%M:%S') 
    delta_second = int((dt - xt).total_seconds()) 
    normalize_second = (delta_second/interval) * interval 
    return xt + timedelta(seconds=normalize_second) 

for k, g in groupby(data, key=lambda i: keyfunc(i[1])): 
    # k would be time interval "03/04/2013 13:30:00", "03/04/2013 13:35:00" .... 
    # g would be the level, timestamp pair belong to the interval 
    avg_level = sum([x[0] for x in g])/len(g) 
    results.append((k, avg_level)) 

EDIT1

在GROUPBY功能使用的keyfunc介紹如何劃分物品放入組。 如果兩個項目具有相同的鍵功能返回值,它們將被放置在同一組中。 (僅當這些項目進行排序)

>>> keyfunc('03/04/2013 13:37:20') 
datetime.datetime(2013, 4, 3, 13, 35) 

>>> keyfunc('03/04/2013 13:37:30') 
datetime.datetime(2013, 4, 3, 13, 35) 

# the return value are the same, so 03/04/2013 13:37:20 and 03/04/2013 13:37:30 
# will be consider in the same group. 
+0

lucemia,抱歉,但我很努力地理解keyfunc的目的是什麼,我認爲這是因爲groupby需要作爲一個關鍵的功能?但是,因爲它是以xt作爲起始日期,那麼您提供了您的系列的時間戳作爲參數,並返回您的系列的時間戳?當然,我一定會錯過一些東西..我認爲在dt =上也有一個微小的差異,也normalize_second =爲什麼分開,然後乘以間隔? – matel

+0

keyfunc告訴python如何分割這些項目。它可以分成多種方式,因此我們需要指定正確的方法。查看我的編輯 – lucemia

+0

什麼意思是正確的?將時間戳除以間隔? – matel

0

有幾種方法可以解決這個問題,但是您對時間有效「分檔」。我會用幾個步驟來處理它:

你不想用字符串操作自己解析時間,它會炸燬你的臉;相信我!將時間戳解析爲一個日期時間對象(谷歌應該給你一個很好的答案)。一旦你有了,你可以做很多有趣的事情,比如兩次比較。

既然你有日期時間對象,你可以開始「裝箱」它們。我會假設記錄是有序的。從第一條記錄的時間「03/04/2013 13:37:20」開始,並在「03/04/2013 13:37:00」創建一個新的日期時間對象[提示:在datetime對象上設置秒= 0閱讀]。這是您的第一個「垃圾桶」的開始。現在添加一分鐘到你的開始日期時間[提示:endDT = startDT + timedelta(秒= 60)],這是你的第一個bin的結束。

現在開始檢查記錄,檢查記錄是否小於endDT,如果是,則將其添加到該列表的列表中。如果記錄大於您的endDT,您將進入下一個bin。要啓動新的bin,請在endDT中添加一分鐘,並創建一個新列表來保存這些項目並在循環中保持一致。

一旦你經歷了循環,你可以在列表上運行max/min/avg。理想情況下,您將列表存儲在類似{datetimeObject:[34,23,45,23]}的字典中。這將使打印和分類變得容易。

這不是最有效/靈活/最酷的方法,但我認爲這可能是最有幫助的。

+0

感謝adahlin非常有用 – matel