如何使用Python将复杂嵌套JSON结构转换为CSV文件?求解转换过程中的问题
解决嵌套JSON转CSV/Excel的问题
我来帮你搞定这个多层嵌套JSON转CSV的难题!先看看你的数据结构——它包含了多层嵌套的数组(比如users里的shifts、reports,还有独立的dates数组),同时还有顶层的元数据字段,直接用简单的pandas转换肯定会出问题,我们一步步拆解处理。
为什么第一段代码报错?
你遇到的ValueError: Mixing dicts with non-Series may lead to ambiguous ordering,原因是直接把整个JSON字典传给pd.DataFrame.from_dict()时,pandas无法处理混合结构:里面既有普通的键值对(比如status、token),又有嵌套的字典和数组,它不知道该怎么排列这些数据,所以抛出了错误。
第二段代码的问题在哪?
你只处理了users和shifts,但遗漏了reports、dates以及data里的其他重要字段(比如needs_publish、needs_republish),而且没有把reports里的日期ID和dates数组关联起来,所以输出结果不符合预期。
完整解决方案代码
下面的代码会完整拆解所有嵌套结构,保留所有字段,并且可以分别输出shifts和reports相关的CSV(也可以直接转Excel):
import json import pandas as pd # 加载JSON文件 with open("E:/TP/json_to_csv/json_data.json", "r") as read_file: data = json.load(read_file) # 提取核心数据部分 data_core = data['data'] # 提取顶层元数据(这些字段需要关联到每个用户记录) top_metadata = { 'needs_publish': data_core['needs_publish'], 'needs_republish': data_core['needs_republish'], 'total_overall': data_core['total'] } # 第一步:处理用户数据,添加顶层元数据 users_df = pd.DataFrame(data_core['users']) # 把顶层元数据添加到每个用户行中 for key, val in top_metadata.items(): users_df[key] = val # 第二步:拆解用户的shifts嵌套数组 # 展开shifts数组 users_shifts_df = users_df.explode('shifts', ignore_index=True) # 把shifts字典转换成单独的列 users_shifts_df = pd.concat( [users_shifts_df.drop(['shifts'], axis=1), users_shifts_df['shifts'].apply(pd.Series)], axis=1 ) # 第三步:拆解用户的reports嵌套字典(键是日期ID) def flatten_reports(report_dict): """把reports的字典结构转换成带日期ID的数组""" flattened_reports = [] for date_id, report_list in report_dict.items(): for report in report_list: # 添加日期ID字段,方便后续关联dates数据 report['linked_date_id'] = date_id flattened_reports.append(report) return flattened_reports # 展开reports并转换为列 users_reports_df = users_df.copy() users_reports_df['reports'] = users_reports_df['reports'].apply(flatten_reports) users_reports_df = users_reports_df.explode('reports', ignore_index=True) users_reports_df = pd.concat( [users_reports_df.drop(['reports'], axis=1), users_reports_df['reports'].apply(pd.Series)], axis=1 ) # 第四步:处理dates数组,方便和reports关联 dates_df = pd.DataFrame(data_core['dates']) # 关联reports和dates数据,补充日期的格式化信息 merged_reports_df = pd.merge( users_reports_df, dates_df, left_on='linked_date_id', right_on='id', how='left', suffixes=('_user', '_date') ) # 输出结果:CSV或Excel # 输出shifts相关数据 users_shifts_df.to_csv('E:/TP/json_to_csv/shifts_result.csv', index=False) # 输出关联了日期的reports数据 merged_reports_df.to_csv('E:/TP/json_to_csv/reports_result.csv', index=False) # 如果需要直接输出Excel,替换成to_excel即可(需要安装openpyxl) # users_shifts_df.to_excel('E:/TP/json_to_csv/shifts_result.xlsx', index=False) # merged_reports_df.to_excel('E:/TP/json_to_csv/reports_result.xlsx', index=False)
代码说明
- 我们先提取了顶层的元数据(
needs_publish等),把这些字段添加到每个用户的记录中,确保不会丢失全局信息。 - 对
shifts数组直接用explode展开,再把字典转换成列,保留所有班次信息。 - 针对
reports的特殊字典结构(键是日期ID),我们写了一个小函数把它转换成带日期ID的数组,之后同样展开并转换为列,再和dates数组关联,补充日期的格式化文本。 - 最后可以分别输出
shifts和reports的结果,也可以根据需求合并成一个表格(注意数据粒度,一个用户可能对应多条班次和报告记录)。
内容的提问来源于stack exchange,提问作者Chirag Patankar
相关产品推荐
相关产品推荐

