如果你需要在 Python 中处理一个大的 JSON 文件,会很容易出现耗尽内存的情况。即使原始数据大小小于内存容量,Python 也

会进一步增加内存使用量。这意味着程序会在与磁盘交互时处理缓慢,或在内存不足时崩溃。

一种常见的解决方案是流解析,也就是惰性解析、迭代解析或分块处理。让我们看看如何将此技术应用于 JSON 处理。

问题:Python中加载JSON内存效率低

我们使用这个大小为24MB的JSON文件来举例,它在加载时会对内存产生明显的影响。这个JSON对象是在GitHub中,用户对存

储库执行操作时的事件列表:

python学习交流Q群:903971231###
[{"id":"2489651045","type":"CreateEvent","actor":
{"id":665991,"login":"petroav","gravatar_id":"","url":"https://api.github.com/users/petroav","avatar_url":"https://avatars.githubusercontent.com/u/665991?"},"repo":
{"id":28688495,"name":"petroav/6.828","url":"https://api.github.com/repos/petroav/6.828"},"payload":
{"ref":"master","ref_type":"branch","master_branch":"master","description":"Solution to homework and assignments from MIT's 6.828 (Operating Systems Engineering). Done in my spare time.","pusher_type":"user"},"public":true,"created_at":"2015-01-01T15:00:00Z"},
...

我们的目标是找出给定用户在与哪些存储库进行交互。下面是一个简单的 Python 程序:

import json
with open("large-file.json", "r") as f:
    data = json.load(f)
user_to_repos = {}
for record in data:
    user = record["actor"]["login"]
    repo = record["repo"]["name"]
    if user not in user_to_repos:
        user_to_repos[user] = set()
    user_to_repos[user].add(repo)

输出结果是一个用户名映射到存储库名称的字典。我们使用 Fil 内存分析器运行它时,可以发现内存使用的峰值达到了124MB,还可以发现两个主要的内存分配来源:

1.读取文件

2.将生成的字节解码为 Unicode 字符串

但我们加载的原始文件是24MB。一旦我们将它加载到内存中并将其解码为文本 (Unicode)Python 字符串,它需要的空间远远超过

24MB。这是为什么?

扩展知识:Python字符串的内存表示

Python字符串在表示时会被更少使用内存的方法优化。每个字符串都有固定的开销,如果字符串可以表示为 ASCII,则每个字符

只使用一个字节的内存。如果字符串使用更多扩展字符,则每个字符可能使用4个字节。我们可以使用 sys.getsizeof() 查看一个对

象需要多少内存:

>>> import sys
>>> s = "a" * 1000
>>> len(s)
>>> sys.getsizeof(s)
>>> s2 = "❄" + "a" * 999
>>> len(s2)
>>> sys.getsizeof(s2)
>>> s3 = "💵" + "a" * 999
>>> len(s3)
>>> sys.getsizeof(s3)

在上面的例子中3个字符串都是 1000 个字符长,但它们使用的内存量取决于它们包含的字符。

在本例中我们的大JSON 文件里包含不适合ASCII编码的字符,正是因为它是作为一个巨大的字符串加载的,所以整个巨大的字符

串会使用效率较低的内存表示。

流处理解决方案

很明显,将整个JSON文件直接加载到内存中是一种内存浪费。

对一个结构为对象列表的 JSON 文件,理论上我们可以一次解析一个块,而不是一次全部解析,以此来减少内存的使用量。目前

有许多 Python 库支持这种 JSON 解析方式,下面我们使用 ijson 库来举例。

PYTHON学习交流Q群:903971231###
import ijson
user_to_repos = {}
with open("large-file.json", "r") as f:
    for record in ijson.items(f, "item"):
        user = record["actor"]["login"]
        repo = record["repo"]["name"]
        if user not in user_to_repos:
            user_to_repos[user] = set()
        user_to_repos[user].add(repo)

如果使用json标准库,数据一旦被加载文件就会被关闭。而使用ijson,文件必须保持打开状态,因为当我们遍历记录时,JSON

解析器正在按需读取文件。有关更多详细信息,请参阅 ijson 文档。

在内存分析器运行它时,可以发现内存使用的峰值降到了3.6MB,问题解决了!而且在此例子中,使用 ijson 的流式处理也会提升

运行时的性能,当然这个性能取决于数据集或算法。
在这里插入图片描述

其他解决方法

•Pandas:Pandas 具有读取 JSON 的能力,理论上它可以以更节省内存的方式读取。

•SQLite:SQLite 数据库可以解析 JSON,将 JSON 存储在列中,以及查询 JSON数据。因此,可以将 JSON 加载到磁盘支持的

数据库文件中,并对它运行查询来提取相关的数据子集。

最后,如果可以控制输出格式,则可以通过切换到更高效的表示来减少 JSON 处理的内存使用量。例如,从单个巨大的 JSON 对

象列表切换到每行一条 JSON 记录,这意味着每条解码的 JSON 记录将只使用少量内存。

如果你需要在 Python 中处理一个大的 JSON 文件,会很容易出现耗尽内存的情况。即使原始数据大小小于内存容量,Python 也会进一步增加内存使用量。这意味着程序会在与磁盘交互时处理缓慢,或在内存不足时崩溃。一种常见的解决方案是流解析,也就是惰性解析、迭代解析或分块处理。让我们看看如何将此技术应用于 JSON 处理。问题:Python中加载JSON内存效率低我们使用这个大小为24MB的JSON文件来举例,它在加载时会对内存产生明显的影响。这个JSON对象是在GitHub中,用户对存储库执行操作时的事 import json analysis_root_dir = D:\\analysis_data\json_file store_result=D:\\analysis_data\\analysis_result\\dependency.csv def parse_dir(root_dir): path = Path(root_dir) all_json_
今天在帮前端准备数据的时候,需要把数据格式转成json格式,说实话,涉及到中文有时候真的是很蛋疼,除非对Python的编码规则比较了解,不然处理起来真的很蛋疼。 我们需要处理的是把一些文章处理,生成多个html文件,然后用json来显示文章的列表,图片,摘要和标题。 为了以后的数据扩展,那必须有一个数据库,我的想法就是自己写一个简单的网页做为提交输入,然后post到后台以后录入到数据库中,再写一个展示文章的页面,展示效果正确后,写一个requests动态的把所有的数据都爬下来生成一个一个的html文档。最后的json数据我只要从数据库把数据抽出来生成就行了。 其实前端的东
json文件过大时,使用内置的json模块解析会报错,后发现ijson模块可以很好的解决这个问题: 参考:Python解析超大json数据(GB级别) 使用过程中,还发现使用ijson,能较好的发现json文件是否有问题。例如,使用ijson读取一个json文件后,如果该json文件本身有问题,它会显示的报错错误: Traceback (most recent call last): File "E:/test/work/myspider/test/read_json.py", line 2
Json文件查看器是一个用来查看Json文件的的绿色软件????。 【无惧大小】可以快速打开GB单位的Json文件。 【支持拖拽】人性化设计之一,支持直接将Json文件拖拽打开。 【支持搜索】人性化设计之一,支持搜索Json文件中的内容。 【历史记录】人性化设计之一,通过历史记录可以快速打开之前的Json文件。 【不收费】免费使用,没有任何套路。用收费的标准,做免费的产品。 极速下载-蓝奏云:http
Java解析JSON文件解决方案之JsonReader 一,使用背景 之前遇到一个需求,是需要将一个json文件解析存储到数据库中。一开始测试的时候,json文件的大小都在几兆以内,所以直接将json文件转化为字符串,再转化成JSONObject对象进行处理时不会出现问题,如下所示: File file = new File("") try(FileInputStream fileInputStream = new FileInputStream(file)) { int size = fileI
本文实例为大家分享了python实现批处理文件的具体代码,供大家参考,具体内容如下 Windows下的bat, linux 下的shell 用来做批处理都很好用,可惜不通用 用 Python 来做就简单多了,不过一条条写代码来调用系统命令也够烦的了 程序员都很懒, 不愿做机械无谓的重复性工作, 干脆自己实现一个. 用法超级简单, 默认会执行一个自定义的 batch.json, 按顺序一条条执行其中的步骤 {steps: {step:df -h,desc:display disk space usage}, {step:date,desc:dis
Python优越的灵活性和易用性使其成为最受欢迎的编程语言之一,尤其是对数据科学家而言。 这在很大程度上是因为使用Python处理大型数据集是很简单的一件事情。 如今,每家科技公司都在制定数据战略。 他们都意识到,拥有正确的数据(干净、尽可能多)会给他们带来关键的竞争优势。 数据,如果使用有效,可以提供深层次的、隐藏在表象之下的信息。 多年来,数据存储的可能格式显著增加,但是,在日常使用中,还是以 CSV 、 JSON 和 XML 占主导地位。 在本文中,我将与你分享在Python中使用这三种流行数据格式及其之间相互转换的最简单方法! CSV 数据 CSV文件是存储数据的最常见方式,你会发现,
本文实例讲述了Python实现的读写json文件功能。分享给大家供大家参考,具体如下: 相比java,pythonjson文件处理简单很多。java操作json文件的话需要引用jar包及相关依赖包,想用java操作json的同学可以去百度,这里就不赘述了。 首先说读json文件 在进行json操作之前,首先要了解json的格式,分辨json文件json文件格式一般有两种: 第一种:每行一个json类似于以下这种形式: ["name":"Tony","age":"21","hobbies" : ["basketball","tennis"]] ["name":"Lisa","age"
使用python实现dict和json字符串的互相转换,以及相应的文件读入和存取操作。相当于实现了简单jsonlib。对于Python的学习有一定的帮助。 主要的类是JsonParser,对外的接口在JsonParser里有定义,对外的接口均有详细的注释。最主要就是注意转义符的处理了,特别是unicode转义符。