python - 将 Python 字典列表转换为按键分组的字典排序列表
问题描述
我需要帮助在 Python 中按键对字典列表进行分组。我有听写列表:
raw_values = [
{'qty': 1, 'price': 11.0, 'name': 'Name 1', 'id': '111'},
{'qty': 2, 'price': 22.0, 'name': 'Name 2', 'id': '111'},
{'qty': 3, 'price': 33.0, 'name': 'Name 3', 'id': '111'},
{'qty': 0, 'price': 12.0, 'name': 'Name 1', 'id': '222'},
{'qty': 3, 'price': 13.0, 'name': 'Name 2', 'id': '222'},
{'qty': 7, 'price': 14.0, 'name': 'Name 2', 'id': '333'},
{'qty': 10, 'price': 15.0, 'name': 'Name 3', 'id': '333'}]
基于该列表,我需要创建一个新的字典列表,我可以在其中按“id”键对记录进行分组,还可以正确重命名和填充其他列 - 名称和数量(如果不是某些“id”的任何记录,我需要将它们留空)。期望的输出:
sorted_values = [
{"id": "111",
"name_1_price": 11.0, "name_1_qty": 1,
"name_2_price": 22.0, "name_2_qty": 2,
"name_3_price": 33.0, "name_3_qty": 3},
{"id": "222",
"name_1_price": 12.0, "name_1_qty": 0,
"name_2_price": 13.0, "name_2_qty": 3,
"name_3_price": None, "name_3_qty": None
},
{"id": "333",
"name_1_price": None, "name_1_qty": None,
"name_2_price": 14, "name_2_qty": 7,
"name_3_price": 15.0, "name_3_qty": 10
}
]
我试图寻找解决方案,我认为我需要使用itertools.groupby
函数按“id”键进行分组。但我不知道 - 我如何按 'id' 分组并根据 'name' 中的值重命名和填充字典?
解决方案
熊猫解决方案:
import pandas as pd
raw_values = [
{'qty': 1, 'price': 11.0, 'name': 'Name 1', 'id': '111'},
{'qty': 2, 'price': 22.0, 'name': 'Name 2', 'id': '111'},
{'qty': 3, 'price': 33.0, 'name': 'Name 3', 'id': '111'},
{'qty': 0, 'price': 12.0, 'name': 'Name 1', 'id': '222'},
{'qty': 3, 'price': 13.0, 'name': 'Name 2', 'id': '222'},
{'qty': 7, 'price': 14.0, 'name': 'Name 2', 'id': '333'},
{'qty': 10, 'price': 15.0, 'name': 'Name 3', 'id': '333'}]
#create DataFrame from dictionary
df = pd.DataFrame(raw_values)
print (df)
id name price qty
0 111 Name 1 11.0 1
1 111 Name 2 22.0 2
2 111 Name 3 33.0 3
3 222 Name 1 12.0 0
4 222 Name 2 13.0 3
5 333 Name 2 14.0 7
6 333 Name 3 15.0 10
#change value to lower and replace empty spaces
df['name'] = df['name'].str.lower().str.replace('\s+','_')
#reshape by unstack, sorting
df = df.set_index(['id','name']).unstack().sort_index(level=1, axis=1).swaplevel(1,0,axis=1)
#flatten MultiIndex
df.columns = df.columns.map('_'.join)
df = df.reset_index()
#convert NaN to None
df = df.mask(df.isnull(), None)
#convert to list of dicts
L = df.to_dict(orient='records')
print (L)
[{'id': '111',
'name_1_price': 11.0, 'name_1_qty': 1.0,
'name_2_price': 22.0, 'name_2_qty': 2.0,
'name_3_price': 33.0, 'name_3_qty': 3.0},
{'id': '222',
'name_1_price': 12.0, 'name_1_qty': 0.0,
'name_2_price': 13.0, 'name_2_qty': 3.0,
'name_3_price': None, 'name_3_qty': None},
{'id': '333',
'name_1_price': None, 'name_1_qty': None,
'name_2_price': 14.0, 'name_2_qty': 7.0,
'name_3_price': 15.0, 'name_3_qty': 10.0}]
推荐阅读
- java - 在控制器中映射 URL(从相关表中删除数据) Spring Boot
- javascript - Bootstrap 将样式应用于表单中不需要的输入。
- delphi - TidHTTP Request 在 Fiddler 运行时有效,但在关闭时无效
- grpc - gPRC如何将数组数据从服务器发送到客户端[gPRC + Node.js]
- d3.js - 如果要缩放,要计算缩放和平移的转换值
- css - mat-form-field 样式如何自动填充标签?
- python - 使用具有不同数据框形状的 matplotlib 绘制条形图
- powershell - 从 CMD 使用时如何正确引用 PowerShell 命令路径
- c++ - `BOOST_ENDIAN_BIG_BYTE` 和 `BOOST_ENDIAN_BIG_WORD` 有什么区别?
- amazon-web-services - 让 SSL 在 AWS on Ghost 中工作 by bitnami