Средние значения во всех диктовках с соответствующими значениями для данного ключа в Python - PullRequest
0 голосов
/ 07 октября 2018

У меня есть список словарей, которые имеют одинаковые ключи.

in_list = [{'index':1, 'value':2.}, {'index':1, 'value':3.}, {'index':2, 'value':4.}]

Я хотел бы создать новый словарь со средним значением 'value' для каждого 'index'.

out_dict = {1:2.5, 2:4.}

Какой самый питонский способ сделать это?


Следующий код делает то, что я хочу, но я чувствую, что он неуклюжий

tmp = {x:[] for x in range(1,3)}
for el in in_list:
    tmp[el['index']].append(el['value'])

for key, val in tmp.iteritems():
    out_dict[key] = sum(val)/len(val)

Ответы [ 4 ]

0 голосов
/ 07 октября 2018

Ваш код в порядке, но вы можете сделать его немного более компактным.Как показывает ответ Transhuman, вы можете избежать инициализации tmp, сделав из него defaultdict списков.Другой способ сделать это - использовать метод dict.setdefault.А затем используйте диктовку для вычисления средних значений.

in_list = [
    {'index':1, 'value':2.}, 
    {'index':1, 'value':3.}, 
    {'index':2, 'value':4.}
]

out_dict = {}
for d in in_list:
    out_dict.setdefault(d['index'], []).append(d['value'])
out_dict = {k: sum(v) / len(v) for k, v in out_dict.items()}
print(out_dict)

output

{1: 2.5, 2: 4.0}
0 голосов
/ 07 октября 2018

Чтобы сделать это без каких-либо пакетов для установки (длинный однострочный :-)):

import itertools,statistics
a = dict(zip(sorted(set([i['index'] for i in lod])),[statistics.mean(int(item['value']) for item in group) for key, group in itertools.groupby(lod, key=lambda x: x['index'])]))

Сейчас:

print(a)

Возвращает:

{1: 2.5, 2: 4}

Если python 2:

import itertools
a = dict(zip(sorted(set([i['index'] for i in lod]),key=[i['index'] for i in lod].index),[sum(int(item['value']) for item in group)/len(int(item['value']) for item in group) for key, group in itertools.groupby(lod, key=lambda x: x['index'])]))

Объяснение:

  • получить упорядоченный список уникальных элементов, используя set

  • используйте itertools.groupby для группировки, затем итерируйте по key a group, получите среднее значение, используя statistics или sum и len

  • все два вышеупомянутых примечания находятся в zip (dict(zip(...)))

Или, чтобы сделать код немного чище:

Python 3:

import itertools,statistics
unique_elements=sorted(set([i['index'] for i in lod]))
groups=statistics.mean(int(item['value']) for item in group) for key, group in itertools.groupby(lod, key=lambda x: x['index'])]
a = dict(zip(unique_elements,groups))

Python 2:

import itertools
unique=sorted(set([i['index'] for i in lod])
groups=[sum(int(item['value']) for item in group)/len(int(item['value']) for item in group) for key, group in itertools.groupby(lod, key=lambda x: x['index'])]
a = dict(unique,groups))
0 голосов
/ 07 октября 2018

Один из способов сделать это - использовать collections.defaultdict

in_list = [{'index':1, 'value':2.}, {'index':1, 'value':3.}, {'index':2, 'value':4.}]

from collections import defaultdict
d_dict = defaultdict(list)
for k,v in [d.values() for d in in_list]:
    d_dict[k].append(v)

{k:sum(v)/len(v) for k,v in d_dict.items()}
#{1: 2.5, 2: 4.0}
0 голосов
/ 07 октября 2018

Я не думаю, что ваш код неуклюж, но вы можете проверить pandas.

>>> import pandas as pd
>>> in_list = [{'index':1, 'value':2.}, {'index':1, 'value':3.}, {'index':2, 'value':4.}]
>>> 
>>> df = pd.DataFrame(in_list)
>>> df.groupby(by='index').mean()
       value
index       
1        2.5
2        4.0

Вы можете преобразовать результат в стандартный словарь, если хотите.

>>> df.groupby(by='index').mean().to_dict()['value']
{1: 2.5, 2: 4.0}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...