Группировка сообщений по временным интервалам



В настоящее время я пытаюсь сгруппировать сообщения, которые отправляются с интервалом в 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 in: [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: группировка результатов по временным интервалам



(я понимаю, что подразделения будут отключены для того, что я хочу, но я просто смотрю на общее идея...)



До сих пор мне в основном не везло, и я был бы признателен за любую помощь.



Также,
Данные выглядят следующим образом:



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

2 ответов:

Предполагая, что вы хотите сгруппировать ваши данные по тем, которые были выданы в течение 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

Это проще, если вы не основываете свою сетку на временных интервалах с разделением пополам.

Вместо этого сделайте вот что. Преобразуйте каждый интервал в одно число.
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 секунд и начинается в эпоху.

Comments

    Ничего не найдено.