Группировка сообщений по временным интервалам
В настоящее время я пытаюсь сгруппировать сообщения, которые отправляются с интервалом в 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]
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.*).Пример использования:
P.S. В этом примере для# 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)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