Добавить значения в независимые словари, когда значения представляют собой (2x2) массивы numpy

Предположим, у меня есть два словаря с одинаковыми ключами, и все значения представляют собой массивы 2x2 numpy. Предположения:

  • словари имеют одинаковые ключи
  • каждое значение представляет собой массив 2x2 для всех словарей и ключей.

x1 и x2 — примеры словарей.

x1 =  {k: np.random.randint(20, size=(2, 2)) for k in range(5)}
x2 =  {k: np.random.randint(20, size=(2, 2)) for k in range(5)}

Я хотел бы добавить x1 и x2 вместе по их ключам, и результатом будет новый словарь.

So if...

  x1[0] = [[1,2],[3,4]] 

и...

  x2[0] = [[10,20],[30,40]]

новое значение словаря, когда ключ = 0, будет...

  x_total[0] = [[11,22],[33,44]]

Следующим шагом будет сделать это для многих словарей с такой структурой. Я думал сделать это в цикле for, но если есть более эффективные решения, я хотел бы узнать о них.

Я пробовал подход ниже, используя библиотеку коллекций

from collections import Counter
a = Counter(x1[0])
b = Counter(x2[0])
c = dict(a + b)

но я думаю, что это может не применяться, если значения являются массивами.

Я также знаю, что np.add(x1[0], x2[0]) приведет к добавлению массивов, но я хотел бы сделать это сразу для всех ключей... если это возможно.


person Sheila    schedule 28.11.2018    source источник


Ответы (3)


Просто используйте понимание словаря:

{k: x1.get(k,0) + x2.get(k,0) for k in set(x1)}

Например:

import numpy as np

np.random.seed(0)

x1 =  {k: np.random.randint(20, size=(2, 2)) for k in range(5)}
x2 =  {k: np.random.randint(20, size=(2, 2)) for k in range(5)}

Урожайность:

{0: array([[12, 15],
       [ 0,  3]]), 1: array([[ 3,  7],
       [ 9, 19]]), 2: array([[18,  4],
       [ 6, 12]]), 3: array([[ 1,  6],
       [ 7, 14]]), 4: array([[17,  5],
       [13,  8]])}

{0: array([[ 9, 19],
       [16, 19]]), 1: array([[ 5, 15],
       [15,  0]]), 2: array([[18,  3],
       [17, 19]]), 3: array([[19, 19],
       [14,  7]]), 4: array([[0, 1],
       [9, 0]])}

Тогда применяя наше решение, мы получаем:

{0: array([[21, 34],
       [16, 22]]), 1: array([[ 8, 22],
       [24, 19]]), 2: array([[36,  7],
       [23, 31]]), 3: array([[20, 25],
       [21, 21]]), 4: array([[17,  6],
       [22,  8]])}
person rahlf23    schedule 28.11.2018

Предполагая, что все словари заполнены (все они имеют одинаковые ключи), понимание словаря должно быть эффективным решением:

 x3 = {key: sum(x1[key] + x2[key]) for key in x1}
person artona    schedule 28.11.2018

Я использую более короткие структуры данных для удобства чтения и предполагаю, что x1 и x2 имеют одни и те же ключи.

>>> x1 = {k:np.arange(k, k+2) for k in range(2)}
>>> x2 = {k:np.arange(k+1, k+3) for k in range(2)}
>>> 
>>> x1
{0: array([0, 1]), 1: array([1, 2])}
>>> x2
{0: array([1, 2]), 1: array([2, 3])}
>>>
>>> x_total = {k: x1[k] + x2[k] for k in x1}
>>> x_total
{0: array([1, 3]), 1: array([3, 5])}

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

person timgeb    schedule 28.11.2018