2012-01-11 52 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