使用Pandas格式化JSON文件时字符串数据缺失(显示NaN)问题排查
问题描述
有一批格式混乱的JSON文件,需要转换为特定结构的Excel文件。已实现将数据解析到Pandas DataFrame的逻辑,但目前代码仅能加载int类型数据,字符串类型数据无法正常加载,输出结果中多个应包含数据的字段显示为NaN。
问题原因分析
- JSON重复键被覆盖:示例JSON中每个
passes项的arguments字段包含多个同名的NOMINAL键,标准JSON解析会自动覆盖重复键,导致仅保留最后一个NOMINAL值,后续分组时无法正确匹配数据。 - 未提取
values字段数据:原代码直接将cells转换为DataFrame,但cells中的实际内容存储在values数组中,未对该字段进行解析提取。 - 列映射不匹配:原代码给DataFrame指定的列名(如
arguments.NOMINAL)与cells的实际结构不符,导致对应列全为NaN。
修正后的代码
import pandas as pd import json from collections import defaultdict # 自定义JSON解析器,处理重复键,将同名键的值转为列表 def json_load_with_duplicates(file_path): def parse_object(pairs): obj = defaultdict(list) for key, value in pairs: obj[key].append(value) return dict(obj) with open(file_path, 'r') as f: return json.load(f, object_pairs_hook=parse_object) # 加载数据 data = json_load_with_duplicates(r"PATH") # 准备结果列表 result_rows = [] for pass_item in data['passes']: name = pass_item['name'] type_ = pass_item['type'] # 获取NOMINAL列表,若不存在则设为空列表 nominal_list = pass_item.get('arguments', {}).get('NOMINAL', []) cells = pass_item.get('cells', []) for cell in cells: row = { 'name': name, 'type': type_, 'id': cell['id'], 'onset': cell['onset'], 'offset': cell['offset'] } # 提取cell中的values数组,长度不足时补空字符串 values = cell.get('values', []) # 将values映射到对应的NOMINAL列 for idx, nominal in enumerate(nominal_list): row[nominal] = values[idx] if idx < len(values) else '' # 处理超出NOMINAL数量的values(如Comments内容) if len(values) > len(nominal_list): row['Comments'] = values[len(nominal_list)] result_rows.append(row) # 转换为DataFrame df = pd.DataFrame(result_rows) # 可选:若需要按数字列名(0/1/2/3)展示,替换以下代码 # base_cols = ['name', 'type', 'id', 'onset', 'offset'] # num_cols = [str(i) for i in range(len(nominal_list))] # if 'Comments' in df.columns: # num_cols.append('Comments') # df.columns = base_cols + num_cols print(df) # 保存为Excel文件 # df.to_excel('formatted_output.xlsx', index=False)
代码说明
- 重复键处理:通过
object_pairs_hook自定义解析逻辑,将重复的NOMINAL键值收集为列表,避免数据丢失。 - 数据映射:遍历每个
cell,将values数组中的内容与对应的NOMINAL列关联,确保字符串数据被正确提取到DataFrame中。 - 灵活列适配:根据
NOMINAL的数量动态生成列名,也可通过注释代码切换为数字列名,适配不同输出需求。
内容的提问来源于stack exchange,提问作者Florian
相关产品推荐
相关产品推荐

