2

我做了一个代码,它在下面生成随机数,并将它们保存在一个 csv 中,如下所示,我正在尝试按函数进行分组学习。例如,我想按时间戳对这些组进行总和或平均值。我是 Python 新手,但我找不到任何开始的地方。Ulitmately 我想做同样的事情,但 1 分钟或 5 分钟(从 00:00:00 开始每 5 分钟一次,在我下面的示例中没有足够的数据,但会做类似 13:35:00 到 13:40:00 的事情下一个 13:40:00 包括到 13:45:00 排除等),我想我可以计算出从时间戳中提取分钟部分的 1 分钟,但 5 分钟似乎很复杂。不要求复制粘贴代码,但我不知道从哪里开始说实话。

级别时间戳
99 2013 年 3 月 4 日 13:37:20
98 2013 年 3 月 4 日 13:37:20
98 2013 年 3 月 4 日 13:37:20
99 2013 年 3 月 4 日 13:37:20
105 2013 年 3 月 4 日 13:37:20
104 2013 年 3 月 4 日 13:37:20
102 2013 年 3 月 4 日 13:37:21
102 2013 年 3 月 4 日 13:37:21
103 2013 年 3 月 4 日 13:37:22
82 2013 年 3 月 4 日 13:37:23
83 2013 年 3 月 4 日 13:37:23
82 2013 年 3 月 4 日 13:37:23
83 2013 年 3 月 4 日 13:37:23
54 2013 年 3 月 4 日 13:37:24
55 2013 年 3 月 4 日 13:37:24
54 2013 年 3 月 4 日 13:37:24
55 2013 年 3 月 4 日 13:37:24
56 2013 年 3 月 4 日 13:37:25
57 2013 年 3 月 4 日 13:37:25
4

2 回答 2

3

它可以用 itertools http://docs.python.org/2/library/itertools.html#itertools.groupby来完成

但要小心:

每次键函数的值发生变化时,它都会生成一个中断或新组(这就是为什么通常需要使用相同的键函数对数据进行排序的原因)。

一个示例用法:

如果您的数据已作为 Level 、时间戳对的列表进行处理。

data = [(99, '03/04/2013 13:37:20'), (98,  '03/04/2013 13:37:20'), ...]

并且您想通过 5 分钟间隔的数据对组进行 AVG

data.sort(key=lambda i: i[1]) # sort with timestamp
results = []

def keyfunc(timestamp, interval = 5*60):
    # defined a key function.
    # 1. parse the datetime string to datetime object
    # 2. count the time delta (seconds)
    # 3. divided the time delta with interval, which is (6*60) here
    xt = datetime(2013, 4,3)
    dt = datetime.strptime(timestamp, '%d/%m/%Y %H:%M:%S')
    delta_second = int((dt - xt).total_seconds())
    normalize_second = (delta_second / interval) * interval
    return xt + timedelta(seconds=normalize_second)

for k, g in groupby(data, key=lambda i: keyfunc(i[1])):
    # k would be time interval "03/04/2013 13:30:00", "03/04/2013 13:35:00" .... 
    # g would be the level, timestamp pair belong to the interval
    avg_level = sum([x[0] for x in g]) / len(g)
    results.append((k, avg_level))

编辑1

groupby 函数中keyfunc使用的函数告诉如何将项目分组。如果两个 item 的 key function 的返回值相同,它们将被放在同一个 group 中。(仅当这些项目已排序时)

>>> keyfunc('03/04/2013 13:37:20')
datetime.datetime(2013, 4, 3, 13, 35)

>>> keyfunc('03/04/2013 13:37:30')
datetime.datetime(2013, 4, 3, 13, 35)

# the return value are the same, so 03/04/2013 13:37:20 and 03/04/2013 13:37:30
# will be consider in the same group. 
于 2013-04-03T15:58:06.193 回答
0

有几种方法可以解决这个问题,但你实际上是在“分箱”。我会分几步来处理它:

你不想用字符串操作自己解析时间,它会在你的脸上爆炸;相信我!将时间戳解析为日期时间对象(谷歌应该给你一个很好的答案)。一旦你有了它,你就可以做很多有趣的事情,比如比较两次。

现在您有了日期时间对象,您可以开始“装箱”它们。我假设记录是有序的。从第一条记录的时间“03/04/2013 13:37:20”开始,并在“03/04/2013 13:37:00”处创建一个新的日期时间对象[提示:在你的日期时间对象上设置秒数=0读入]。这是您的第一个“bin”的开始。现在为您的开始日期时间添加一分钟 [提示:endDT = startDT + timedelta(seconds=60)],这是您的第一个 bin 的结束。

现在开始检查您的记录,检查记录是否小于您的 endDT,如果是,请将其添加到该 bin 的列表中。如果记录大于您的 endDT,则您在下一个 bin 中。要启动新的 bin,请在 endDT 中添加一分钟并创建一个新列表来保存这些项目并在循环中继续前进。

完成循环后,您可以在列表上运行 max/min/avg。理想情况下,您会将列表存储在类似于 {datetimeObject : [34, 23, 45, 23]} 的字典中。它将使打印和分类变得容易。

这不是最有效/最灵活/最酷的方式,但我认为它可能是最有帮助的开始。

于 2013-04-03T15:40:41.490 回答