如何将1NF格式的Pandas DataFrame转换为含字典列表的单列
解决Pandas DataFrame分组生成嵌套字典列表(适配OpenSearch嵌套索引)
先假设你的原始1NF格式DataFrame示例如下:
import pandas as pd df = pd.DataFrame({ 'Code': ['A001', 'A001', 'A001', 'A002', 'A002'], 'alias': ['别名1', '别名1', '别名2', '别名3', '别名3'], 'provtype': ['类型X', '类型Y', '类型X', '类型Z', '类型X'], 'specCode': ['S001', 'S002', 'S001', 'S003', 'S001'] })
核心实现代码(两次GroupBy)
先按Code+alias聚合去重,再按Code打包成字典列表:
# 1. 聚合同一Code+alias下的provtype和specCode为列表(可选去重) grouped = df.groupby(['Code', 'alias']).agg( provtypelist=('provtype', lambda x: pd.unique(x).tolist()), # 保留顺序的去重 specCodeList=('specCode', lambda x: pd.unique(x).tolist()) ).reset_index() # 2. 按Code分组,生成每个组的aliasList字典列表 result = grouped.groupby('Code').agg( aliasList=('alias', lambda x: [ {'alias': row['alias'], 'provtypelist': row['provtypelist'], 'specCodeList': row['specCodeList']} for _, row in grouped[grouped['Code'] == x.name].iterrows() ]) ).reset_index()
代码说明
- 用
pd.unique(x).tolist()替代list(set(x))是为了保留原始数据的顺序,不需要去重的话直接用list(x)即可。 - 第二次GroupBy中,通过
x.name获取当前分组的Code值,筛选对应行后逐行生成符合要求的字典,最终打包为列表。
OpenSearch嵌套类型适配
生成的result中,aliasList字段正好是OpenSearch嵌套类型要求的对象数组结构。你可以直接通过result.to_dict('records')将数据转为字典列表,然后批量写入OpenSearch索引。
其他可行方案
紧凑版(单GroupBy+嵌套Apply)
适合小数据集,写法更简洁:
result = df.groupby('Code').apply( lambda g: pd.Series({ 'aliasList': g.groupby('alias').apply( lambda subg: { 'alias': subg['alias'].iloc[0], 'provtypelist': pd.unique(subg['provtype']).tolist(), 'specCodeList': pd.unique(subg['specCode']).tolist() } ).tolist() }) ).reset_index()
简化版(单alias对应单行数据)
如果同一Code下每个alias只对应一行原始数据,可直接省略第一次聚合:
result = df.groupby('Code').agg( aliasList=('Code', lambda x: [ {'alias': row['alias'], 'provtypelist': [row['provtype']], 'specCodeList': [row['specCode']]} for _, row in df[df['Code'] == x.name].iterrows() ]) ).reset_index()
内容的提问来源于stack exchange,提问作者BrownBatman
相关产品推荐
相关产品推荐

