Python中如何高效读取4GB以上的大JSON文件到内存?
尝试用 pickle.loads 读到内存,直接内存溢出了,试着用 pandas.read_json()读取,但是报错,Excepted object or value 黔驴技穷,不知道该咋弄了
Python中如何高效读取4GB以上的大JSON文件到内存?
要不你试试用工具把内存映射成硬盘,然后当作硬盘读写?
不过貌似没有长期免费的内存映射硬盘工具
对于读取4GB以上的大JSON文件,传统方法如json.load()会一次性加载整个文件到内存,容易导致内存溢出。这里推荐几种高效处理大JSON文件的方法:
1. 使用ijson库进行流式解析
import ijson
def process_large_json(file_path):
with open(file_path, 'rb') as f:
# 流式解析JSON数组中的每个对象
objects = ijson.items(f, 'item')
for obj in objects:
# 逐条处理数据
process_single_item(obj)
2. 使用jsonlines格式(如果文件是每行一个JSON对象)
import json
def read_jsonlines(file_path):
with open(file_path, 'r', encoding='utf-8') as f:
for line in f:
data = json.loads(line.strip())
# 处理单条数据
3. 分块读取结合json.loads
def read_json_in_chunks(file_path, chunk_size=1024*1024): # 1MB chunks
buffer = ""
with open(file_path, 'r', encoding='utf-8') as f:
while True:
chunk = f.read(chunk_size)
if not chunk:
break
buffer += chunk
# 这里需要根据JSON结构实现更复杂的分块解析逻辑
4. 使用pandas的chunksize参数(如果文件是JSON数组)
import pandas as pd
chunk_size = 10000
for chunk in pd.read_json('large_file.json', lines=True, chunksize=chunk_size):
# 处理每个数据块
process_dataframe(chunk)
建议:对于4GB以上的JSON文件,优先考虑ijson进行流式解析。
这么大还用 json 不太合适吧……
某些数据库已经支持 Json 数据类型了,先塞进去,Py 再去读 DB 呢?
加内存,就是这么直接
才 4 个 G 不会爆内存的吧…你内存不够了?
自己写个 json 解释器,支持流式读取
开一个临时的大内存云服务器
pip install ijson
你这 json 什么结构啊…如果层数深还是长度长?
Memory-mapped file
https://docs.python.org/3.0/library/mmap.html
将你的需求映射为数据接口由 c++来处理,C++用 rapidjson 来读取
rapidjson 如果还是不行,就用 c++写一个针对文件的、有限功能的 json 库
如果自己搞不定,就外包
建议使用 less 这种文本阅读工具看一下内容,然后根据内容用代码一部分一部分的读然后切成小文件,应该是比较快的方法。
为什么不先导入到数据库
搞策略交易么
#9 楼 回复正解。迭代式解析 json 即可。内存绝对不会爆炸。
没接触过这种工具,推荐一个谢谢啦
你说为啥 load 的时候,会达到文件本身 10 倍的内存占用呢,是因为 Python 的数据类型导致的吗
哎,我老大写的代码,要我优化,他服务器 32 个 G 的内存,给我开了一个 8G 的,我跑代码特么的动不动就内存溢出。真的头大
真粗暴,有没有什么免费的骚操作
文件大小虽然是 4 个 G,但是 load 的时候会造成很多倍的内存占用,也不知道为什么
大佬,可以来个示范代码或者链接吗,万分感激
公司 32G 的服务器,也会跑崩
查阅相关资料的时候看到这个库,我去了解一下
字典,嵌套字典
这算一个临时的中间文件,所以没有保存数据库
Python 版本倒是 64 位的其他就不知道了
小弟的水平看来只能 GG 了
单机 spark 试试?
rapidjson,用 SAX+流式。
https://github.com/Tencent/rapidjson
导 mongodb 里 
首先,先搞清楚你把数据加载到内存后打算干吗。
这坨数据就是比你内存大,和格式无关。哪怕它是再精简不过的 bin 格式,哪怕我用 c,都无法解决 8G 内存读取 800G 数据的矛盾。
唯一的出路,就是根据数据格式和需求确定解析和计算模式,部分解析,部分计算,分治然后汇总。
建议的几种读取方式:
1,SAX 了解一下,事件流驱动的 xml 解析思路,搬到 json 上毫无问题。
2,切割原 json 文件,给它补上恰当的开始、关闭符来确保结构。
3,自己实现解析器,最 low 的状态机实现起来很简单的。然后一边解析一边处理一边丢弃。
4,如果 json 数据有某种特征,预处理一下。(比如结构体其实不复杂元素也不多,但里面有个字段的值超大,那么先文本处理 json,把这个字段抽取出来形成外部文件,json 内只留个文件名索引)其实很多超大数据集要么结构简单只是数据条数多,要么条数不多但单条比较大,很容易做针对性处理。
这是使用 generator 的最佳场景呀,流式读取和解析~~~
这个本来是很多个文件处理后生成的一个字典,然后用 pickle dump 出去,生成一个临时中间文件,避免下次使用的时候还要经过计算生成,但是在 load 的时候,不知道为什么内存占用会成倍的增长。
这就是典型设计问题啊
有流式解析的 不过这要看你的数据本身的结构 34 楼已经说得很清楚了
with as 😯
请装 16G 的内存,谢谢。
临时加个 swapfile
4 个 G 数据,加载到内存可远远不止 4G
加内存咯…不过全部加载到内存干什么…
NoSQL
如果都是条数多,嵌套层数少,相同元素多,可以流式读取文件,generator 处理啊
额 是我的描述出了点问题,pickle.dump 是异于 json.dump 的,是一个超大的字典,dump 出去有 4 个多 G,但是 load 的时候内存占用成倍的增长,直接溢出
文件达到将近 5 个 G 的时候,32G 内存服务器偶尔会崩。。。。
是啊,我原以为这两个库作用是相同的,查阅资料的时候才发现是有区别的,误导了大家了,尴尬
谢谢,我去了解一下
是啊,pickle dump 出去只有 4 个 G,load 进来的时候却成倍的增长,是不是因为数据结构的原因呢
是经过处理计算的一个字典,为了减少下次运算时间,所以打算用空间换取时间,dump 出一个中间临时文件,到时候直接 load 进来的
如果用 nosql,我想了一下,对于 redis,貌似只能用 hash 类型,但是这个字典里面有嵌套,要保存的话,还是需要序列化
大多数应用程序都必须检索整个对象,然后仅过滤出所需数据以进行进一步分析。借助 S3 Select,应用程序可以将过滤和访问对象内部数据的繁重工作卸载到 Amazon S3 服务。
https://aws.amazon.com/cn/about-aws/whats-new/2018/04/amazon-s3-select-is-now-generally-available/?nc1=f_ls
你老大 32G 内存,你就和你老大说一下不就完了吗。需求不合理就提。
这么大,知道数据结构的话慢慢读,不用一次性 load 啊
pickle dump 出去的,怎么慢慢读呢
自己搞一个数据结构存放文件吧,json 的文件是有深度的,有些时候不读取完毕很难读取到一个 object 的内容。
用 生成器呀


