如何用Pandas将大型CSV转换为指定嵌套JSON结构?
如何用Pandas将CSV数据转换为指定嵌套JSON结构?
问题描述
我有一份大型CSV文件,格式示例如下:
PN,PCA Code,MPN Code,DATE_CODE,Supplier Code,CM Code,Fiscal YEAR,Fiscal MONTH,Usage,Defects 13-1668-01,73-2590,MPN148,1639,S125,CM1,2017,5,65388,0 20-0127-02,73-2171,MPN170,1707,S125,CM1,2017,9,11895,0 19-2472-01,73-2302,MPN24,1711,S119,CM1,2017,10,4479,0 20-0127-02,73-2169,MPN170,1706,S125,CM1,2017,9,7322,0 20-0127-02,73-2296,MPN170,1822,S125,CM1,2018,12,180193,0 15-14399-01,73-2590,MPN195,1739,S133,CM6,2018,11,1290,0
需要按PCA Code对所有数据分组,生成如下嵌套JSON结构:
[ { "PCA": { "code": "73-2590", "CM": ["CM1", "CM6"], "parts": [ { "number": "13-1668-01", "manufacturer": [ { "id": "MPN148", "info": [ { "date_code": 1639, "supplier": { "id": "S125", "FYFM": "2017-5", "usage": 65388, "defects": 0 } } ] } ] }, { "number": "15-14399-01", "manufacturer": [ { "id": "MPN195", "info": [ { "date_code": 1739, "supplier": { "id": "S133", "FYFM": "2018-11", "usage": 1290, "defects": 0 } } ] } ] } ] } }, // 其他PCA分组的内容... ]
我目前用Pandas处理,但卡在嵌套结构的实现上,现有代码如下:
import json import pandas as pd dataframe = pd.read_csv('files/dppm_wc.csv') data = {'PCAs': []} for key, group in dataframe.groupby('PCA Code'): for index, row in group.itterrows(): # 这里还有个拼写错误:itterrows → iterrows temp_dict = {'PCA Code': key, 'CM Code': row['CM Code'], 'parts': []} with open('output.txt', 'w') as file: file.write(json.dumps(data, indent=4))
请问如何实现期望的嵌套JSON格式?是否有更优方案?
解决方案
核心思路
我们需要从最外层到最内层逐层构建嵌套结构:
- 按
PCA Code分组,每个PCA对应一个对象,包含去重的CM列表、parts列表 - 每个
part对应唯一的PN,包含manufacturer列表 - 每个
manufacturer对应唯一的MPN Code,包含info列表 - 每个
info对应一行原始数据的细节,包含date_code和supplier对象
完整实现代码
首先修正你代码里的拼写错误(itterrows改为iterrows),然后通过多层分组和字典构建来实现嵌套:
import json import pandas as pd # 读取CSV数据 df = pd.read_csv('files/dppm_wc.csv') # 最终结果列表 result = [] # 第一层:按PCA Code分组 for pca_code, pca_group in df.groupby('PCA Code'): # 收集当前PCA下的所有CM Code(去重) cm_list = list(pca_group['CM Code'].unique()) # 构建parts列表:按PN分组 parts = [] for pn, pn_group in pca_group.groupby('PN'): # 构建manufacturer列表:按MPN Code分组 manufacturers = [] for mpn, mpn_group in pn_group.groupby('MPN Code'): # 构建info列表:遍历每一行数据 info = [] for _, row in mpn_group.iterrows(): # 构建supplier对象 supplier = { "id": row['Supplier Code'], "FYFM": f"{row['Fiscal YEAR']}-{row['Fiscal MONTH']}", "usage": row['Usage'], "defects": row['Defects'] } info.append({ "date_code": row['DATE_CODE'], "supplier": supplier }) manufacturers.append({ "id": mpn, "info": info }) parts.append({ "number": pn, "manufacturer": manufacturers }) # 构建当前PCA的完整对象 result.append({ "PCA": { "code": pca_code, "CM": cm_list, "parts": parts } }) # 写入JSON文件 with open('output.json', 'w') as f: json.dump(result, f, indent=4)
更优方案:利用Pandas的groupby.apply减少循环
如果你的CSV文件非常大,多层for循环可能会影响效率,我们可以用groupby.apply结合自定义函数来更高效地构建嵌套结构:
import json import pandas as pd df = pd.read_csv('files/dppm_wc.csv') def build_info(row): return { "date_code": row['DATE_CODE'], "supplier": { "id": row['Supplier Code'], "FYFM": f"{row['Fiscal YEAR']}-{row['Fiscal MONTH']}", "usage": row['Usage'], "defects": row['Defects'] } } def build_manufacturer(group): return { "id": group.name, "info": group.apply(build_info, axis=1).tolist() } def build_part(group): manufacturers = group.groupby('MPN Code').apply(build_manufacturer).tolist() return { "number": group.name, "manufacturer": manufacturers } def build_pca(group): parts = group.groupby('PN').apply(build_part).tolist() return { "PCA": { "code": group.name, "CM": list(group['CM Code'].unique()), "parts": parts } } # 生成最终结果 result = df.groupby('PCA Code').apply(build_pca).tolist() # 写入文件 with open('output_optimized.json', 'w') as f: json.dump(result, f, indent=4)
这种方式利用了Pandas的内置分组优化,比纯Python循环更适合处理大型数据集,代码结构也更清晰,每一层的职责明确。
注意事项
- 确保CSV中的字段名和代码里的引用完全一致(比如你的示例里是
Fiscal YEAR,代码里要保留空格或者用引号访问) - 如果需要处理空值,可以在构建字典时加上判空逻辑,比如
row.get('Supplier Code', '') - 生成JSON时,如果数值类型需要严格匹配(比如
date_code是整数),Pandas会自动保留原始类型,无需额外转换
内容的提问来源于stack exchange,提问作者user14604054
相关产品推荐
相关产品推荐

