2012-01-11 89 views
2

我目前正在嘗試對按1秒時間間隔發送的消息進行分組。我目前正在計算時間延遲與此:按時間間隔對消息進行分組

def time_deltas(infile): 
entries = (line.split() for line in open(INFILE, "r")) 
ts = {} 
for e in entries: 
    if " ".join(e[2:5]) == "T out: [O]": 
     ts[e[8]] = e[0]  
    elif " ".join(e[2:5]) == "T in: [A]":  
     in_ts, ref_id = e[0], e[7] 
     out_ts = ts.pop(ref_id, None) 
     yield (float(out_ts),ref_id[1:-1],(float(in_ts)*1000 - float(out_ts)*1000)) 

INFILE = 'C:/Users/klee/Documents/test.txt' 
import csv 

with open('test.csv', 'w') as f: 
csv.writer(f).writerows(time_deltas(INFILE)) 

不過,我想計算的「T在:[A]」的數量派出每秒的消息,並已試圖與這個合作,這樣做的:

import datetime 
import bisect 
import collections 

data=[ (datetime.datetime(2010, 2, 26, 12, 8, 17), 5594813L), 
    (datetime.datetime(2010, 2, 26, 12, 7, 31), 5594810L), 
    (datetime.datetime(2010, 2, 26, 12, 6, 4) , 5594807L), 
] 
interval=datetime.timedelta(seconds=50) 
start=datetime.datetime(2010, 2, 26, 12, 6, 4) 
grid=[start+n*interval for n in range(10)] 
bins=collections.defaultdict(list) 
for date,num in data: 
idx=bisect.bisect(grid,date) 
    bins[idx].append(num) 
for idx,nums in bins.iteritems(): 
print('{0} --- {1}'.format(grid[idx],len(nums))) 

可以在這裏找到:Python: group results by time intervals

(我知道單位會關閉我想要的東西,但我只是尋找到的總體思路...)

到目前爲止,我一直未能成功,並希望得到任何幫助。

而且,出現 的數據爲:

082438.577652 - T in: [A] accepted. ordID [F25Q6] timestamp [082438.575880] RefNumber [6018786] State [L] 

回答

3

假設您希望將數據按照秒數在1秒內發佈的數據進行分組,我們可以利用這樣一個事實,即您的數據是有序的,並且int(out_ts)會將時間戳截斷爲第二個,我們可以將其用作分組鍵。

最簡單的做法分組是使用itertools.groupby

from itertools import groupby 

data = get_time_deltas(INFILE) 
get_key = lambda x: int(x[0]) # function to get group key from data 
bins = [(k, list(g)) for k, g in groupby(data, get_key)] 

bins將是一個元組的列表,其中元組的第一個值是關鍵(整數,例如082438),第二個值是那一秒發佈的數據條目列表(時間戳= 082438.*)。

實例:

# print out the number of messages for each second 
for sec, data in bins: 
    print('{0} --- {1}'.format(sec, len(data))) 

# write (sec, msg_per_sec) out to CSV file 
import csv 
with open("test.csv", "w") as f: 
    csv.writer(f).writerows((s, len(d)) for s, d in bins) 

# get average message per second 
message_counts = [len(d) for s, d in bins] 
avg_msg_per_second = float(sum(message_count))/len(message_count) 

P.S.在這個例子中,list用於bins,以便維護數據的順序。如果您需要隨機訪問數據,請考慮使用OrderedDict


請注意,將解決方案以幾秒爲單位進行調整是相對直接的。例如,爲了通過每分鐘(60秒)的消息組,改變get_key功能:

get_key = lambda x: int(x[0]/60) # truncate timestamp to the minute 
+0

謝謝!這很令人驚訝。 :D – eunhealee 2012-01-13 18:09:26

+0

非常歡迎。 – 2012-01-13 19:20:24

+0

對不起,我該如何將它寫入csv文件? – eunhealee 2012-01-13 19:49:56

1

這是比較容易,如果你不平分基礎上的時間間隔網格。

取而代之,請執行此操作。將每個間隔轉換爲一個數字。

def map_time_to_interval_number(epoch, times) 
    for t in times: 
     delta= (t - epoch) 
     delta_t= delta.days*60*60*24 + delta.seconds + delta.microseconds/1000000.0 
     interval = delta_t/50 
     yield interval, t 

counts = defaultdict(int) 
epoch = min(data) 
for interval, time in map_time_to_interval_number(epoch, data): 
    counts[interval] += 1 

間隔將是一個整數。 0是第一個50秒間隔。 1是第二個50秒間隔。等等。

您可以從知道每個間隔寬度爲50秒並從紀元開始的時間間隔重建時間戳。

+0

我在使用這種困難: NameError:名稱「defaultdict」沒有定義。 我很抱歉,如果我只是不熟悉這一點。 – eunhealee 2012-01-11 21:39:06

+0

您遇到問題了,因爲Google壞了。這是Google搜索「python defaultdict」的第一個搜索結果。 http://docs.python.org/library/collections.html閱讀並理解這個庫很重要。 – 2012-01-11 21:40:12