Добавляйте значения в независимые словари, когда значения являются (2x2) массивами - PullRequest
0 голосов
/ 28 ноября 2018

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

  • словари имеют одинаковые ключи
  • каждое значение является массивом 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 вместе по ключам, и в результате получился бы новый словарь.

Так что, если ...

  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]) приведет к добавлению массивов, но я бы хотел сделать это одновременно для всех клавиш ... если возможно.

Ответы [ 3 ]

0 голосов
/ 28 ноября 2018

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

 x3 = {key: sum(x1[key] + x2[key]) for key in x1}
0 голосов
/ 28 ноября 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])}

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

0 голосов
/ 28 ноября 2018

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

{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]])}
...