[英]How to sum elements in list of dictionaries if two key values are the same
I have the following list of dictionaries: 我有以下词典列表:
dictionary =[{'Flow': 100, 'Location': 'USA', 'Name': 'A1'},
{'Flow': 90, 'Location': 'Europe', 'Name': 'B1'},
{'Flow': 20, 'Location': 'USA', 'Name': 'A1'},
{'Flow': 70, 'Location': 'Europe', 'Name': 'B1'}]
I want to create a new list of dictionaries, with summed Flow
values of all dictionaries where Location
and Name
are the same. 我想创建一个新的字典列表,其中包含所有字典的总和
Flow
值,其中Location
和Name
是相同的。 My desired output would be: 我想要的输出是:
new_dictionary =[{'Flow': 120, 'Location': 'USA', 'Name': 'A1'},
{'Flow': 160, 'Location': 'Europe', 'Name': 'B1'},]
How can I achieve this? 我怎样才能做到这一点?
This is possible, but non-trivial to implement in python. 这是可能的,但在python中实现并不重要。 Might I suggest using pandas?
我可以建议使用熊猫吗? This is simple with a
groupby
, sum
, and to_dict
. 这对于
groupby
, sum
和to_dict
很简单。
import pandas as pd
(pd.DataFrame(dictionary)
.groupby(['Location', 'Name'], as_index=False)
.Flow.sum()
.to_dict('r'))
[{'Flow': 160, 'Location': 'Europe', 'Name': 'B1'},
{'Flow': 120, 'Location': 'USA', 'Name': 'A1'}]
To install, use pip install --user pandas
. 要安装,请使用
pip install --user pandas
。
Otherwise, you can apply a pseudo-generic group operation using itertools.groupby
. 否则,您可以使用
itertools.groupby
应用伪通用组操作。
from itertools import groupby
from operator import itemgetter
grouper = ['Location', 'Name']
key = itemgetter(*grouper)
dictionary.sort(key=key)
[{**dict(zip(grouper, k)), 'Flow': sum(map(itemgetter('Flow'), g))}
for k, g in groupby(dictionary, key=key)]
[{'Flow': 160, 'Location': 'Europe', 'Name': 'B1'},
{'Flow': 120, 'Location': 'USA', 'Name': 'A1'}]
While I would also prefer using Pandas if possible, here is solution using plain python: 虽然如果可能的话我也更喜欢使用Pandas,这里是使用普通python的解决方案:
In [1]: import itertools
In [2]: dictionary =[{'Flow': 100, 'Location': 'USA', 'Name': 'A1'},
...: {'Flow': 90, 'Location': 'Europe', 'Name': 'B1'},
...: {'Flow': 20, 'Location': 'USA', 'Name': 'A1'},
...: {'Flow': 70, 'Location': 'Europe', 'Name': 'B1'}]
...:
In [3]: import operator
In [4]: key = operator.itemgetter('Location', 'Name')
In [5]: [{'Flow': sum(x['Flow'] for x in g),
...: 'Location': k[0],
...: 'Name': k[1]}
...: for k, g in itertools.groupby(sorted(dictionary, key=key), key=key)]
...:
...:
Out[5]:
[{'Flow': 160, 'Location': 'Europe', 'Name': 'B1'},
{'Flow': 120, 'Location': 'USA', 'Name': 'A1'}]
Another way is to use defaultdict, which gives you a slightly different representation (though you can convert it back to list of dicts if you want): 另一种方法是使用defaultdict,它会给你一个稍微不同的表示(尽管如你所愿你可以将它转换回dicts列表):
In [11]: import collections
In [12]: cnt = collections.defaultdict(int)
In [13]: for r in dictionary:
...: cnt[(r['Location'], r['Name'])] += r['Flow']
...:
In [14]: cnt
Out[14]: defaultdict(int, {('Europe', 'B1'): 160, ('USA', 'A1'): 120})
In [15]: [{'Flow': x, 'Location': k[0], 'Name': k[1]} for k, x in cnt.items()]
Out[15]:
[{'Flow': 120, 'Location': 'USA', 'Name': 'A1'},
{'Flow': 160, 'Location': 'Europe', 'Name': 'B1'}]
Not exactly the output you expect, but.. 不完全是你期望的输出,但..
Using collections.Counter()
使用
collections.Counter()
count = Counter()
for i in dictionary:
count[i['Location'], i['Name']] += i['Flow']
print count
Will give: 会给:
Counter({ ('Europe', 'B1'): 160,
('USA', 'A1'): 120 })
I hope this will at least give you some idea. 我希望这至少会给你一些想法。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.