Python实现大体积异构键非标准JSON转CSV及URL解码
大体积行式JSON转CSV可落地方案
针对非标准逐行存储JSON(JSONL格式)、键不统一、含URL编码值的场景,核心解决思路是全程流式逐行读写,不一次性加载全量文件到内存,从根源避免大文件处理时的电脑卡死问题。
核心实现逻辑拆解
- 动态收集所有JSON条目出现过的全部键,自动合并为CSV统一表头
- 逐行解析JSON对象,匹配表头时缺失的键自动填充空值
- 对字符串类型的取值按需做URL解码
- 逐行写入CSV,全程内存占用保持在单条JSON对象的大小,无内存暴涨问题
方案1:Python标准库实现(适配GB级以上超大文件,零第三方依赖)
全程仅依赖Python自带模块,内存占用极低,哪怕10G+的文件也能稳定处理。
依赖模块
json:逐行解析单条JSON对象csv:按标准格式写入CSV文件urllib.parse.unquote:处理URL编码的字符串值
可直接运行的代码
import json import csv from urllib.parse import unquote # 基础配置,替换成你自己的文件路径 INPUT_PATH = "your_input.jsonl" OUTPUT_PATH = "result.csv" # 若仅需对特定字段做URL解码,将字段名填入列表即可;填None表示对所有字符串值做解码 DECODE_TARGET_FIELDS = None # 第一阶段:逐行扫描收集所有出现过的JSON键,生成CSV表头 all_field_keys = set() with open(INPUT_PATH, "r", encoding="utf-8") as f: for line in f: line = line.strip() if not line: # 跳过空行 continue current_obj = json.loads(line) all_field_keys.update(current_obj.keys()) # 排序固定表头顺序,避免每次运行生成的列顺序混乱 all_field_keys = sorted(all_field_keys) # 第二阶段:逐行处理数据、写入CSV with open(INPUT_PATH, "r", encoding="utf-8") as fin, \ open(OUTPUT_PATH, "w", encoding="utf-8-sig", newline="") as fout: csv_writer = csv.DictWriter(fout, fieldnames=all_field_keys) csv_writer.writeheader() # 先写入表头 for line in fin: line = line.strip() if not line: continue current_obj = json.loads(line) processed_row = {} for key in all_field_keys: # 无对应键的条目直接取空值 value = current_obj.get(key, "") # 按配置做URL解码 if isinstance(value, str): if DECODE_TARGET_FIELDS is None or key in DECODE_TARGET_FIELDS: value = unquote(value) processed_row[key] = value csv_writer.writerow(processed_row)
方案优势
- 全程两次顺序读取文件,从不把全量数据加载到内存,从根源避免程序卡死
- 自动适配不同JSON条目的键差异,缺失值自动填充空字符串
- 写入时用
utf-8-sig编码,避免用Excel打开CSV时出现中文乱码
方案2:pandas快速实现(适配MB~GB级中小体积文件)
如果你的文件体积远小于电脑内存,可以用更简洁的pandas代码快速实现,不需要手动写遍历逻辑。
可直接运行的代码
import pandas as pd from urllib.parse import unquote # 读取逐行存储的JSON,关键参数是lines=True,自动识别JSONL格式 # 不同行的键不统一时,pandas会自动合并为表头,缺失值默认填充NaN df = pd.read_json("your_input.jsonl", lines=True, encoding="utf-8") # 对所有字符串类型的列做URL解码 str_columns = df.select_dtypes(include="object").columns df[str_columns] = df[str_columns].applymap( lambda x: unquote(x) if isinstance(x, str) else x ) # 保存为CSV,na_rep参数把空值替换为空字符串,避免默认显示NaN df.to_csv("result.csv", index=False, na_rep="", encoding="utf-8-sig")
注意事项
- 这个方法会把全量文件加载到内存,当文件体积超过可用内存的1/3时,就会出现运行卡顿,此时请切换到标准库实现的方案
- 读取时的
lines=True参数是核心,缺失这个参数pandas会按标准单JSON结构解析文件,出现格式报错
常见踩坑提示
- 之前程序卡死的核心原因大多是用
json.load()一次性加载整个大文件到内存,触发系统内存交换机制,导致整机卡顿,流式逐行处理是目前处理大JSONL文件最可靠的方案 unquote函数对未编码的正常字符串不会产生破坏,可以放心对全量字符串字段做解码处理
内容的提问来源于stack exchange,提问作者Roxbip
相关产品推荐
相关产品推荐

