Как мне легко манипулировать ключом метки времени в словаре Python? - PullRequest
2 голосов
/ 08 января 2011

Я только начал использовать Python как хобби, так что простите, если это глупый вопрос.

Я недавно установил измеритель мощности на своем компьютере и использую его для отслеживания потребления энергии. Это дает мне минутные показания в реальном времени, экспортированные в CSV-файл.

Я проанализировал и прочитал файл, и теперь у меня есть словарь, в котором ключом является метка времени, сохраненная как struct_time из библиотеки времени. В настоящее время в словаре есть чтения, которые снимались каждую минуту. Я хотел бы создать новый словарь, ключи которого являются часовыми метками времени, а значения - это сумма отдельных минутных показаний.

Я думал о циклическом просмотре словаря с помощью счетчика модов 60, но мне сказали, что это не очень Pythonic. Кроме того, нет гарантии, что существует 60 показаний за каждый час. Как мне это сделать?

Ответы [ 3 ]

9 голосов
/ 08 января 2011

Если мое понимание вашего вопроса верно, это должно сделать работу:

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

Преимущество использования defaultdict состоит в том, что он будет обрабатывать случай пропущенных часов, возвращая 0 в качестве значения.

Edit:

Как указал Кристиан, ОП может иметь показания в течение нескольких дней. В этом случае я следую предложению, впервые внесенному Адамом Розенфилдом, с небольшой модификацией:

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

Это построит дату из дня, месяца, года и часа без минут или секунд.

4 голосов
/ 08 января 2011

Во-первых, я бы предложил использовать класс 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)))
0 голосов
/ 08 января 2011

Одна строка в 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)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...