Group by multiple keys and summarize/average values of a list of dictionaries

后端 未结 7 1264
梦谈多话
梦谈多话 2020-11-30 01:03

What is the most pythonic way to group by multiple keys and summarize/average values of a list of dictionaries in Python please? Say I have a list of dictionaries as below:<

7条回答
  •  天命终不由人
    2020-11-30 01:29

    To get the aggregated results

    from itertools import groupby
    from operator import itemgetter
    
    grouper = itemgetter("dept", "sku")
    result = []
    for key, grp in groupby(sorted(input_data, key = grouper), grouper):
        temp_dict = dict(zip(["dept", "sku"], key))
        temp_dict["qty"] = sum(item["qty"] for item in grp)
        result.append(temp_dict)
    
    from pprint import pprint
    pprint(result)
    

    Output

    [{'dept': '001', 'qty': 200, 'sku': 'bar'},
     {'dept': '001', 'qty': 400, 'sku': 'foo'},
     {'dept': '002', 'qty': 900, 'sku': 'baz'},
     {'dept': '002', 'qty': 600, 'sku': 'qux'},
     {'dept': '003', 'qty': 700, 'sku': 'foo'}]
    

    And to get the averages, you can simply change the contents inside the for loop, like this

    temp_dict = dict(zip(["dept", "sku"], key))
    temp_list = [item["qty"] for item in grp]
    temp_dict["avg"] = sum(temp_list) / len(temp_list)
    result.append(temp_dict)
    

    Output

    [{'avg': 200, 'dept': '001', 'sku': 'bar'},
     {'avg': 200, 'dept': '001', 'sku': 'foo'},
     {'avg': 450, 'dept': '002', 'sku': 'baz'},
     {'avg': 600, 'dept': '002', 'sku': 'qux'},
     {'avg': 700, 'dept': '003', 'sku': 'foo'}]
    

    Suggestion: Anyway, I would have added both the qty and avg in the same dict like this

    temp_dict = dict(zip(["dept", "sku"], key))
    temp_list = [item["qty"] for item in grp]
    temp_dict["qty"] = sum(temp_list)
    temp_dict["avg"] = temp_dict["qty"] / len(temp_list)
    result.append(temp_dict)
    

    Output

    [{'avg': 200, 'dept': '001', 'qty': 200, 'sku': 'bar'},
     {'avg': 200, 'dept': '001', 'qty': 400, 'sku': 'foo'},
     {'avg': 450, 'dept': '002', 'qty': 900, 'sku': 'baz'},
     {'avg': 600, 'dept': '002', 'qty': 600, 'sku': 'qux'},
     {'avg': 700, 'dept': '003', 'qty': 700, 'sku': 'foo'}]
    

提交回复
热议问题