Can*_* Lu 24 python dictionary list
什么是通过多个键进行分组的最pythonic方法,并在Python中汇总字典列表的平均值?假设我有一个字典列表如下:
input = [
{'dept': '001', 'sku': 'foo', 'transId': 'uniqueId1', 'qty': 100},
{'dept': '001', 'sku': 'bar', 'transId': 'uniqueId2', 'qty': 200},
{'dept': '001', 'sku': 'foo', 'transId': 'uniqueId3', 'qty': 300},
{'dept': '002', 'sku': 'baz', 'transId': 'uniqueId4', 'qty': 400},
{'dept': '002', 'sku': 'baz', 'transId': 'uniqueId5', 'qty': 500},
{'dept': '002', 'sku': 'qux', 'transId': 'uniqueId6', 'qty': 600},
{'dept': '003', 'sku': 'foo', 'transId': 'uniqueId7', 'qty': 700}
]
Run Code Online (Sandbox Code Playgroud)
期望的聚合输出:
output=[
{'dept': '001', 'sku': 'foo', 'qty': 400},
{'dept': '001', 'sku': 'bar', 'qty': 200},
{'dept': '002', 'sku': 'baz', 'qty': 900},
{'dept': '002', 'sku': 'qux', 'qty': 600},
{'dept': '003', 'sku': 'foo', 'qty': 700}
]
Run Code Online (Sandbox Code Playgroud)
或平均:
output=[
{'dept': '001', 'sku': 'foo', 'avg': 200},
{'dept': '001', 'sku': 'bar', 'avg': 200},
{'dept': '002', 'sku': 'baz', 'avg': 450},
{'dept': '002', 'sku': 'qux', 'avg': 600},
{'dept': '003', 'sku': 'foo', 'avg': 700}
]
Run Code Online (Sandbox Code Playgroud)
我发现了这个:在Python中分组并汇总字典列表的值,但它似乎没有给我我想要的东西.
the*_*eye 40
获得汇总结果
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)
Run Code Online (Sandbox Code Playgroud)
产量
[{'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'}]
Run Code Online (Sandbox Code Playgroud)
要获得平均值,您可以简单地更改for循环内的内容,就像这样
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)
Run Code Online (Sandbox Code Playgroud)
产量
[{'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'}]
Run Code Online (Sandbox Code Playgroud)
建议:无论如何,我会添加qty和这样avg的相同dict
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)
Run Code Online (Sandbox Code Playgroud)
产量
[{'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'}]
Run Code Online (Sandbox Code Playgroud)
灵感来自Eelco Hoogendoorn的回答.这是使用Pandas包解决此问题的另一种方法.代码更具可读性.
import numpy as np
import pandas as pd
def sum_by_cusip_and_dept(data):
df = pd.DataFrame(data)
grouped = df.groupby(['sku', 'dept'])
sum = grouped.sum()
return [{'sku': r[0], 'dept': r[1], 'qty': kv.to_dict().get('qty')} for r, kv in sum.iterrows()]
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
17082 次 |
| 最近记录: |