假设我有以下列表:
[{'name': 'Amy', 'count': 1}, {'name': 'Amy', 'count': 2}, {'name': 'Peter', 'count': 1}]
我如何对其进行分组并对计数求和以获得以下结果:
[{'name': 'Amy', 'count': 3}, {'name': 'Peter', 'count': 1}]
感谢。
答案 0 :(得分:5)
您可以使用collecions.Counter
:
from collections import Counter
l = [
{'name': 'Amy', 'count': 1},
{'name': 'Amy', 'count': 2},
{'name': 'Peter', 'count': 1}
]
c = Counter()
for v in l:
c[v['name']] += v['count']
结果:
>>> c
Counter({'Amy': 3, 'Peter': 1})
>>> [{'name': name, 'count': count} for name, count in c.items()]
[{'count': 3, 'name': 'Amy'}, {'count': 1, 'name': 'Peter'}]
答案 1 :(得分:3)
您也可以使用Pandas groupby功能:
df = pd.DataFrame([{'name': 'Amy', 'count': 1},
{'name': 'Amy', 'count': 2},
{'name': 'Peter', 'count': 1}])
df.groupby("name").sum()
count
name
Amy 3
Peter 1
答案 2 :(得分:1)
您可以使用defaultdict
in the doc解释列表:
>>> l = [{'name': 'Amy', 'count': 1},
{'name': 'Amy', 'count': 2},
{'name': 'Peter', 'count': 1}]
# Pivot operation
>>> pivot = collections.defaultdict(list)
>>> for item in l:
... pivot[item['name']].append(item['count'])
...
>>> pivot
defaultdict(<class 'list'>, {'Peter': [1], 'Amy': [1, 2]})
之后,您只需使用理解列表重建我们想要的输出:
>>> [{'name':k, 'count':sum(values)} for k, values in pivot.items()]
[{'name': 'Peter', 'count': 1}, {'name': 'Amy', 'count': 3}]
我必须承认这不是最有效的方法,但考虑到你的数据结构,我想枢轴操作在其他几个场景中会很有用,不一定意味着总结。
答案 3 :(得分:1)
import itertools as it
import operator as op
l = [{'name': 'Amy', 'count': 1}, {'name': 'Amy', 'count': 2}, {'name': 'Peter', 'count': 1}]
获取按dict的'name'键排序的列表。
sl = sorted(l,key=op.itemgetter('name'))
将排序列表传递给gorupby
,其中键作为dict的'name'键,返回键的元组和按dict的'name'键分组的列表项的迭代器。 F.E. ('Amy',<itertools._grouper object at 0xb5fdac2c>)
。
迭代器每次迭代产生一个项目列表的所有元素,其中'Amy'作为dict的'name'键的值。
要获取“计数”键的总和,我们必须使用sum
等所有“计数”字段的新列表来调用sum(map(op.itemgetter('count'),g))
。
构建一个dict调用列表dict
,其中groupby
返回的元组最合适的元素作为'name'键的值,sum
返回的总和作为'的值'计算新词典的关键。
[ dict(name=k,count=sum(map(op.itemgetter('count'),g)))
for k,g in it.groupby(sl, key=op.itemgetter('name'))]
答案 4 :(得分:1)
我想建议你可以使用defaultdict
和answer中的Sylvain Leroux。
但是,没有必要将计数收集到列表中,您可以在使用defaultdict(int)
时将它们相加:
from collections import defaultdict
l = [{'name': 'Amy', 'count': 1}, {'name': 'Amy', 'count': 2}, {'name': 'Peter', 'count': 1}]
counts = defaultdict(int)
for d in l:
counts[d['name']] += d['count']
counts = [{'name': k, 'count': v} for k,v in counts.items()]
>>> print counts
[{'count': 3, 'name': 'Amy'}, {'count': 1, 'name': 'Peter'}]
这应该比构建列表和总结它们更有效。
itertools.groupby
是另一种选择,但它确实需要按name
键排序的前期列表,这可能在较长的列表上效率较低。