如何简单地操作Python字典中的时间戳键?

3 投票
3 回答
6124 浏览
提问于 2025-04-16 09:38

我刚开始把Python当作爱好来学,所以如果这个问题听起来很傻,请多包涵。

我最近在我的电脑上安装了一个电表,用来监测它的电力消耗。这个电表可以实时每分钟给我一个读数,并把数据导出到一个csv文件里。

我已经解析并读取了这个文件,现在我有了一个字典,字典的键是时间戳,存储为time库中的struct_time格式。目前,这个字典里的读数是每分钟记录一次的。我想创建一个新的字典,新的字典的键是小时的时间戳,值是每分钟读数的总和。

我考虑过用一个循环来遍历这个字典,并用一个计数器来判断是否到60,但有人告诉我这样做不太符合Python的风格。而且,也不能保证每个小时都有60个读数。我应该怎么做呢?

3 个回答

0

在Python3中只需要一行代码:

{time.struct_time(i+(0,0,0,0)):sum(k[1] for k in j) for i,j in itertools.groupby(sorted(D.items()),lambda x:x[0][:4])}

在Python2中:

result={}
tmp=(0,)*4
for i,j in itertools.groupby(sorted(D.items()),lambda x:x[0][:4]):
    result[time.struct_time(i+tmp)]=sum(k[1] for k in j)
9

如果我理解你的问题没错,这段代码应该能解决你的问题:

from collections import defaultdict
output = defaultdict(int)
for key, value in readings.iteritems():
    output[key.tm_hour] += value

使用 defaultdict 的好处是,当某些小时的数据缺失时,它会自动返回0作为值。

补充:

正如Cristian提到的,提问者可能会有几天的数据。在这种情况下,我会按照Adam Rosenfield最初提出的建议,稍作修改:

from collections import defaultdict
from datetime import datetime
output = defaultdict(int)
for key, value in readings.iteritems():
    output[datetime(*x[:4])] += value

这段代码会根据日期中的日、月、年和小时来构建日期,但不会包含分钟和秒。

4

首先,我建议你使用 datetime.datetime 这个类,而不是 time.time_struct。因为后者其实只是一个简单的9个元素的组合,而前者是一个功能齐全的类,支持各种操作符重载等功能。接下来,你可以使用 collections.defaultdict 来轻松构建你想要的总读数:

# power_reading is the data type corresponding to one set of power readings
# (it could be a simple float, or a tuple, or a class if you want; just make
# sure that you can add them together)
hourly_readings = collections.defaultdict(power_reading)
minutely_readings = { ... };  # dict of time.struct_time ==> power_reading

for timestamp, reading in minutely_readings.iteritems():
    hour = datetime.datetime(timestamp.tm_year, timestamp.tm_mon,
                             timestamp.tm_mday, timestamp.tm_hour);
    hourly_readings[hour] += reading

如果 power_reading 是一个元组,你就不能用 += 来操作(因为这样会把元组连接在一起,而不是逐个元素相加),所以你需要这样做:

hourly_readings[hour] = tuple(map(sum, zip(hourly_readings[hour], reading)))

撰写回答