Python中如何高效处理一个21GB的JSON文件?

有人跟我说
with open(“file_name”,‘r’) as file:
for line in file:
pass
这样读可以的 有没有更好的方法呀
Python中如何高效处理一个21GB的JSON文件?

31 回复

直接 json.loads

嗯,这个时候就是考验你是不是土豪的时候了😄


直接读进内存肯定不行。我的思路是流式解析,用 ijson 库。它像 SAX 解析 XML 一样,一点一点读 JSON,不一次性加载。

假设你的 21GB JSON 是一个巨大的对象数组,结构像这样:

[
  {"id": 1, "data": "..."},
  {"id": 2, "data": "..."},
  // ... 几十亿条记录
]

可以这样逐条处理:

import ijson
import json

def process_large_json(file_path, output_path):
    with open(file_path, 'rb') as f, open(output_path, 'w') as out_f:
        # 直接定位到数组的每一项
        objects = ijson.items(f, 'item')
        
        # 先写入输出数组的开头
        out_f.write('[')
        first = True
        
        for obj in objects:
            # 处理你的业务逻辑,比如过滤、转换
            processed = {
                'id': obj['id'],
                'summary': obj['data'][:100]  # 示例:只取前100字符
            }
            
            # 逐条写入输出文件
            if not first:
                out_f.write(',')
            json.dump(processed, out_f)
            first = False
            
            # 可选:每处理一定数量打印进度
            if processed['id'] % 1000000 == 0:
                print(f"Processed {processed['id']} items")
        
        # 写入数组结尾
        out_f.write(']')

# 使用
process_large_json('input.json', 'output.json')

如果 JSON 结构不同,比如顶层是个大对象而不是数组,用 ijson.kvitems(f, 'some_key') 来遍历键值对。关键是把文件当流,用 'rb' 二进制模式打开。

内存占用基本是常数,就是慢点,但 21GB 除了流式解析没别的办法。

总结:用 ijson 流式解析,别想着全加载。

楼上坏坏~~~

json 是有一定结构的,你一行一行读了也没法解析呀

分块啊

问题是 json 格式啊 可怜我的小破机器只有 16G 坏银~~

扔进 elk ?

开 swap,存成 hdf 等适合大数据的格式

哪个机器导出来的?这么牛的机器一定也能读吧,让那个机器转成可以分块读取的数据结构再给你

这个库可以读么

丢进 Splunk 吧

从网上下的 dns 记录


就像用本机处理 再开大数据好麻烦。。

凉了 不是 21G 解压之后 127G

https://www.dataquest.io/blog/python-json-tutorial/
不过好像要分行,如果你这个只有 1 行,那我估计你就要先预处理分行了

json.load(f)试试?

DNS 记录也就一行一行的,不会台复杂,直接自己按行读取解析下就好了,又不是未知结构。

类似于 SAX 读取 XML 的方式??? DOM 方式肯定不行了。

JDK 提供的 XML 解析方式分为两种:DOM 方式和 SAX 方式
DOM:Document Object Model。需要读取整个 XML 文档,先需要在内存中构架代表整个 DOM 树的 Document 对象,可以进行随机访问. 需要考虑内存.适合增删改
SAX:Simple API for XML。采用事件驱动的方式解析 XML 文件,边读边对文档进行处理.适合读取

读出来了 很普通的格式 我去想怎么处理啦 谢谢~~~
with open(“file_name”,‘r’) as file:
for line in file:
pass
这样读都是秒读的

自己从头解析啊,深度优先,一层层放入数据库。

#19
SAX +1,边读取边解析边对解析后的数据进行处理

打算这么做了

导入数据库,再通过数据库来

有个流式读取 json 的库 好行叫 jsonstream 来着可以用那个

如果 json 数据不规整,read_json 不会报错吗

mmap 然后用 SAX 的 API 读取。
如果用 C++ 的话,可以试试 rapidjson。

想办法处理一下,把数据搞进数据库。后面玩起来就爽了,elk,postgresql 都支持直接处理 json

搞了下太慢了 最后把首字母排序处理的~~

你得先把这些数据解析一下塞到数据库里面再搞,直接塞,太耗 cpu 内存了。

回到顶部