开发者

How do I easily manipulate a timestamp key in a Python dictionary?

I just started using Python as hobby, so forgive me if this is a dumb question.

I recently installed a power meter on my computer, and I'm using it to track its power consumption. It gives me real-time minute readings exported to a csv file.

I have parsed and read the file, and now I ha开发者_开发问答ve a dictionary where the key is a timestamp, stored as a struct_time from the time library. Currently, the dictionary has readings which were taken every minute. I'd like to create a new dictionary whose keys are hour timestamps, and whose values are the sum of the individual minute readings.

I thought about looping through the dictionary with a counter mod 60, but I'm told that isn't very Pythonic. Also, there's no guarantee that there exists 60 readings for every hour. How should I do this?


If my understanding to your question is right, this should do the job:

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

The advantage of using defaultdict is that it will handle the case of missing hours by returning 0 as a value.

Edit:

As Cristian pointed out the OP might have readings for several days. In that case I follow the suggestion first introduced by Adam Rosenfield with a slight modification:

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

This will construct the date from the day, month, year and hour without minutes or seconds.


First, I'd suggest using the datetime.datetime class instead of time.time_struct, since the latter is really just a weak wrapper around a 9-tuple but the former is a fully-featured class with operator overloads etc. Next, you can use a collections.defaultdict to easily construct your desired total readings:

# 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

If power_reading is a tuple, you can't use += (since that concatenates the tuples instead of doing an element-wise addition), so you'll have to do something like this instead:

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


One line in 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)
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜