【问题标题】:Grouping Messages by Time Intervals按时间间隔分组消息
【发布时间】:2017-09-06 07:20:50
【问题描述】:

我目前正在尝试对按 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: group results by time intervals

(我意识到这些单位会按照我的意愿关闭,但我只是在研究总体思路......)

到目前为止,我大多不成功,希望能提供任何帮助。

另外, 数据显示为:

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

【问题讨论】:

    标签: python datetime itertools


    【解决方案1】:

    假设您希望将您的数据按 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)
    

    附:在此示例中,list 用于bins,以便保持数据的顺序。如果您需要随机访问数据,请考虑改用OrderedDict


    请注意,将解决方案调整为按秒的倍数分组是相对简单的。例如,要按每分钟(60 秒)的消息进行分组,请将 get_key 函数更改为:

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

    【讨论】:

    • 对不起,如何将其写入 csv 文件?
    • 还有一个问题,如果我想计算出消息的数量,我该怎么做?
    • @eunhaelee 您希望将哪些字段写入 csv?
    • 您是指总消息数,还是每个间隔的消息数?
    • 对csv文件重要的内容是python打印的内容。 (例如 120056 - 3)
    【解决方案2】:

    如果您的网格不基于对分的时间间隔,这会更容易。

    相反,请执行此操作。将每个区间转换为单个数字。

    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 秒宽并从纪元开始,您可以根据间隔重建时间戳。

    【讨论】:

    • 我遇到了困难:NameError: name 'defaultdict' is not defined。如果我对此不熟悉,我深表歉意。
    • 您遇到了困难,因为 Google 坏了。这是谷歌搜索“python defaultdict”的第一个命中。 docs.python.org/library/collections.html阅读和理解这个库很重要。
    猜你喜欢
    • 2011-12-20
    • 2011-02-08
    • 2019-06-28
    • 2018-10-12
    • 2017-09-21
    • 2016-09-21
    • 2021-03-06
    • 2016-10-06
    相关资源
    最近更新 更多