Агрегирование словаря с использованием даты и времени - PullRequest
0 голосов
/ 31 января 2019

У меня есть словарь WO в формате:

WO = {datetime: {'V1', 'V2', 'V3', 'V4'}}

, где datetime является ключом (пример) формата:

datetime.date(2014, 6, 20)

И V1до V4 - списки, содержащие плавающие значения.

Пример:

WO = {datetime.date(2014, 12, 20): {'V1': [11, 15, 19], 
                                    'V2': [12, 3, 4], 
                                    'V3': [50, 55, 56], 
                                    'V4': [100, 112, 45]},
      datetime.date(2014, 12, 21): {'V1': [10, 12, 9], 
                                    'V2': [16, 13, 40], 
                                    'V3': [150, 155, 156], 
                                    'V4': [1100, 1132, 457]},
      datetime.date(2014, 12, 22): {'V1': [107, 172, 79], 
                                    'V2': [124, 43, 44], 
                                    'V3': [503, 552, 561], 
                                    'V4': [1000, 1128, 457]}}

Если я хочу агрегировать значения от V1 до V4 в соответствии с неделей для данной датыНапример:

my_date = datetime.date(2014, 5, 23)

Для этой данной даты агрегируйте все значения от V1 до V4 для этой недели, где неделя начинается с понедельника.

year, week, weekday = datetime.date(my_date).isocalendar()

Эта строка дает мне неделю и день недели для этой конкретной даты.

Если у меня есть функция как:

def week(date):
    '''
    date is in 'datetime.date(year, month, date)' format

    This function is supposed to aggregate values in 'V1', 'V2', 'V3' and 
    'V4' for a whole week according to the parameter 'date'
    '''

Как мне продолжить, чтобы определить такую ​​функцию?

Ответы [ 3 ]

0 голосов
/ 31 января 2019

Если я добавлю пропущенные скобки в WO, чтобы избавиться от синтаксических ошибок (которые вы действительно должны были проверить перед публикацией):

WO = {datetime.date(2014, 12, 20): {'V1': [11, 15, 19], 'V2': [12, 3, 4], 'V3': [50, 55, 56], 'V4': [100, 112, 45]}, datetime.date(2014, 12, 22): {'V1': [107, 172, 79], 'V2': [124, 43, 44], 'V3': [503, 552, 561], 'V4': [1000, 1128, 457]}, datetime.date(2014, 12, 21): {'V1': [10, 12, 9], 'V2': [16, 13, 40], 'V3': [150, 155, 156], 'V4': [1100, 1132, 457]}}

Затем я могу сделать это, чтобы увидеть, какие номера неделинаходятся в данных:

>>> for date, values in WO.items():
        year, week, _ = date.isocalendar()
        print (date,year,week)

, и я вижу, что в этом примере вы хотите агрегировать две недели:

2014-12-20 2014 51
2014-12-22 2014 52
2014-12-21 2014 51

То есть ваши данные относятся к неделям ISO 51и 52 из 2014. Вы консолидируете по неделям, поэтому у ваших агрегированных данных будет ключ (year, week), но без дня.(Вам нужен год, потому что в ваших данных могут быть разные годы.) Итак, вы хотите построить dict с ключами (2014, 51) и (2014, 52).У каждого будет 3 значения, связанных с "V1" - "V4", потому что на этой неделе только один день, и консолидировать нечего.Другая неделя будет иметь 6 значений, связанных с "V1" - "V4", поскольку в данных есть две недели для этой недели.

Начните с пустого dict, чтобы содержать сводку:

>>> summary = {}

Перебирайте даты, чтобы найти номера лет и недели, как и раньше, но на этот раз собирайте данные в соответствии с клавишами (year, week):

>>> for date, values in WO.items():
      year, week, _ = date.isocalendar()
      if (year, week) not in summary:
        summary [(year, week)] = {vn: [] for vn in values} # empty lists for vn = 'V1' - 'V4'
      for vn in values:
        summary[(year, week)][vn].extend(values[vn])

>>> summary
{(2014, 51): {'V1': [11, 15, 19, 10, 12, 9], 'V2': [12, 3, 4, 16, 13, 40], 'V3': [50, 55, 56, 150, 155, 156], 'V4': [100, 112, 45, 1100, 1132, 457]}, (2014, 52): {'V1': [107, 172, 79], 'V2': [124, 43, 44], 'V3': [503, 552, 561], 'V4': [1000, 1128, 457]}}
0 голосов
/ 31 января 2019

Вы можете использовать вложенный defaultdict для сбора данных за ту же неделю, используя номер недели в качестве ключа (или некоторый другой хешируемый идентификатор).Затем используйте вложенный словарь для поэлементного суммирования списка списков.

from collections import defaultdict

dd = defaultdict(lambda: defaultdict(list))

for k1, v1 in WO.items():
    for k2, v2 in v1.items():
        dd[k1.isocalendar()[1]][k2].append(v2)

WO_agg = {k1: {k2: list(map(sum, zip(*v2))) for k2, v2 in v1.items()} \
          for k1, v1 in dd.items()}

print(WO_agg)
# {51: {'V1': [21, 27, 28],
#       'V2': [28, 16, 44],
#       'V3': [200, 210, 212],
#       'V4': [1200, 1244, 502]},
#  52: {'V1': [107, 172, 79],
#       'V2': [124, 43, 44],
#       'V3': [503, 552, 561],
#       'V4': [1000, 1128, 457]}}
0 голосов
/ 31 января 2019

из того, что я понял, вы хотите сделать некоторые манипуляции со всеми значениями V1 ... V4 данной недели данной даты.сначала я начну с нахождения понедельника (начало недели) данной даты.

year, week, weekday = my_date.isocalendar()     
last_monday_date = my_date - datetime.timedelta(days = weekday - 1)

даст вам дату последнего понедельника.

, затем вы можете использовать это для диапазона датза дни недели: Создание диапазона дат в Python

и, наконец, в диапазоне дат для цикла итерации по значениям WO и получения результата.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...