简体   繁体   English

根据键值聚合列表中的字典

[英]Aggregating dicts within a list based on key value

I'm struggling to wrap my head around this one.我正在努力解决这个问题。 I've got a list with multiple dictionaries that I would like to aggregate based on two values.我有一个包含多个字典的列表,我想根据两个值进行聚合。 Example code:示例代码:

>>> data = [
...     { "regex": ".*ccc-r.*", "age": 44, "count": 224 },
...     { "regex": ".*nft-r.*", "age": 23, "count": 44 },
...     { "regex": ".*ccc-r.*", "age": 44, "count": 20 },
...     { "regex": ".*ccc-r.*", "age": 32, "count": 16 },
...     { "regex": ".*nft-r.*", "age": 23, "count": 46 },
...     { "regex": ".*zxy-r.*", "age": 16, "count": 55 }
...     ]

I'm trying to aggregate dicts that have the same age and regex and adding the count key across all instances.我正在尝试聚合具有相同年龄和正则表达式的字典,并在所有实例中添加计数键。 Example output would be:示例 output 将是:

>>> data = [
...     { "regex": ".*ccc-r.*", "age": 44, "count": 244 },
...     { "regex": ".*nft-r.*", "age": 23, "count": 90 },
...     { "regex": ".*ccc-r.*", "age": 32, "count": 16 },
...     { "regex": ".*zxy-r.*", "age": 16, "count": 55 }
...     ]

Would like to do this without pandas or addon modules, would prefer a solution from the std lib if at all possible.想要在没有 pandas 或附加模块的情况下执行此操作,如果可能的话,更喜欢 std lib 中的解决方案。

Thanks!谢谢!

You can use collections.defaultdict :您可以使用collections.defaultdict

from collections import defaultdict
d = defaultdict(int)
data = [{'regex': '.*ccc-r.*', 'age': 44, 'count': 224}, {'regex': '.*nft-r.*', 'age': 23, 'count': 44}, {'regex': '.*ccc-r.*', 'age': 44, 'count': 20}, {'regex': '.*ccc-r.*', 'age': 32, 'count': 16}, {'regex': '.*nft-r.*', 'age': 23, 'count': 46}, {'regex': '.*zxy-r.*', 'age': 16, 'count': 55}]
for i in data:
   d[(i['regex'], i['age'])] += i['count']

r = [{'regex':a, 'age':b, 'count':c} for (a, b), c in d.items()]

Output: Output:

[{'regex': '.*ccc-r.*', 'age': 44, 'count': 244}, 
 {'regex': '.*nft-r.*', 'age': 23, 'count': 90}, 
 {'regex': '.*ccc-r.*', 'age': 32, 'count': 16}, 
 {'regex': '.*zxy-r.*', 'age': 16, 'count': 55}]

Assuming you do not want to use any imports, you can first collect the data in a dictionary aggregated_data in which the key will be a tuple of (regex, age) , and the value will be the count .假设您不想使用任何导入,您可以首先将数据收集到字典中的aggregated_data数据中,其中键是(regex, age)的元组,值是count Once you have formed this dictionary, you can form back the original structure you had:一旦你形成了这本字典,你就可以重新形成你原来的结构:

data = [
    { "regex": ".*ccc-r.*", "age": 44, "count": 224 },
    { "regex": ".*nft-r.*", "age": 23, "count": 44 },
    { "regex": ".*ccc-r.*", "age": 44, "count": 20 },
    { "regex": ".*ccc-r.*", "age": 32, "count": 16 },
    { "regex": ".*nft-r.*", "age": 23, "count": 46 },
    { "regex": ".*zxy-r.*", "age": 16, "count": 55 }
]

aggregated_data = {}

for dictionary in data:
    key = (dictionary['regex'], dictionary['age'])
    aggregated_data[key] = aggregated_data.get(key, 0) + dictionary['count']

data = [{'regex': key[0], 'age': key[1], 'count': value} for key, value in aggregated_data.items()]

You can also try,你也可以试试,

agg = {}

for d in data:
    if agg.get(d['regex']):
        agg[d['regex']]['count'] += d['count']
    else:
        agg[d['regex']] = d

print(agg.values())

If you're not opposed to using a library (and a slightly different output) this can be done nicely with pandas如果您不反对使用库(以及稍微不同的输出),则可以使用pandas很好地完成

import pandas as pd

df = pd.DataFrame(data)
data.groupby(['regex', 'age']).sum()

This yields这产生

               count
regex     age
.*ccc-r.* 32      16
          44     244
.*nft-r.* 23      90
.*zxy-r.* 16      55

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM