2012-01-11 6 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. В этом примере для bins использовался list, чтобы сохранить порядок данных. Если вам нужен произвольный доступ к данным, используйте вместо этого OrderedDict.


Обратите внимание, что относительно легко адаптировать решение к группе за несколько секунд. Например, в группе по сообщениям в минуту (60 секунд), измените get_key функцию:

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

Спасибо! Это работает удивительно. : D – eunhealee

+0

Добро пожаловать. –

+0

Извините, как я могу записать его в файл csv? – eunhealee

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

+0

У вас проблемы, потому что Google сломан. Вот первый хит в поиске Google для «python defaultdict». http://docs.python.org/library/collections.html Важно, чтобы вы читали и понимали эту библиотеку. –

Смежные вопросы