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)
精彩评论