如何用Python将100GB大型JSON文件完整加载至内存?
处理100GB大型JSON文件加载问题
问题描述
我有一个大小为100GB的JSON文件,结构如下:
json_f = {"main_index":{"0":3,"1":7},"lemmas":{"0":["test0", "test0"],"1":["test1","test1"]}}
*"lemmas"的每个元素是大型单词列表,长度约为200万条。
最终需求:
- 将"lemmas"完整加载为内存中的列表形式:
[["test0", "test0"], ["test1","test1"]] - 或先加载为
pd.DataFrame,再处理成上述列表形式。
已尝试方法
- 使用
pd.read_json:出现内存错误(本机有256GB内存,并非RAM不足); - 使用
ijson迭代加载:示例数据正常,但真实文件中内核持续忙碌,迭代器无输出:f = open("json_f.json", 'rb') texts = [] for j in ijson.items(f, 'lemmas.0'): texts.append(j) - 考虑拆分文件后合并,但拆分仍需先加载原文件,陷入同样困境。
解决建议
1. 修正ijson迭代路径
你之前的迭代路径仅指向lemmas下的0键,应改为遍历所有子元素,同时添加进度确认避免误以为程序停滞:
import ijson texts = [] with open("json_f.json", 'rb') as f: # 用'lemmas.item'匹配所有子元素 for item in ijson.items(f, 'lemmas.item'): texts.append(item) # 每处理10条打印进度 if len(texts) % 10 == 0: print(f"已加载 {len(texts)} 条数据")
若文件为UTF-8编码,可改用'r'模式打开,避免二进制模式的编码适配问题。
2. 用命令行工具预处理JSON(推荐)
用jq命令行工具直接提取lemmas的所有值并转为每行一个JSON对象的格式,再逐行读取:
# 提取lemmas下的所有列表,每行输出一个 jq -c '.lemmas[]' input.json > lemmas_lines.jsonl
之后用Python逐行加载:
import json texts = [] with open("lemmas_lines.jsonl", 'r') as f: for line in f: lst = json.loads(line.strip()) texts.append(lst)
3. 优化pandas加载策略
pd.read_json的内存错误可能是默认数据类型冗余导致,可指定仅加载目标字段并优化数据类型:
import pandas as pd # 仅加载lemmas字段,指定字符串类型减少内存占用 df = pd.read_json("json_f.json", dtype={'lemmas': 'string'}) # 转换为目标列表格式 texts = list(df['lemmas'].values())
若直接加载仍报错,可先用ijson提取lemmas的键值对再转DataFrame:
import ijson import pandas as pd data = {} with open("json_f.json", 'rb') as f: for key, value in ijson.kvitems(f, 'lemmas'): data[key] = value df = pd.DataFrame.from_dict(data, orient='index') texts = df.values.tolist()
4. 内存映射文件辅助处理
用mmap将文件映射到内存,减少IO开销,提升迭代效率:
import ijson import mmap texts = [] with open("json_f.json", 'r') as f: with mmap.mmap(f.fileno(), length=0, access=mmap.ACCESS_READ) as mm: for item in ijson.items(mm, 'lemmas.item'): texts.append(item)
内容的提问来源于stack exchange,提问作者SollPicher
相关产品推荐
相关产品推荐

