0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

如何将流解析技术应用于JSON处理

Linux爱好者 ? 来源:CSDN技术社区 ? 作者:Python开发者 ? 2022-06-24 12:07 ? 次阅读
加入交流群
微信小助手二维码

扫码添加小助手

加入工程师交流群

如果你需要在 Python 中处理一个大的 JSON 文件,会很容易出现耗尽内存的情况。即使原始数据大小小于内存容量,Python 也会进一步增加内存使用量。这意味着程序会在与磁盘交互时处理缓慢,或在内存不足时崩溃。

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

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

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

[{"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":"SolutiontohomeworkandassignmentsfromMIT's6.828(OperatingSystemsEngineering).Doneinmysparetime.","pusher_type":"user"},"public":true,"created_at":"2015-01-01T1500Z"},
...
]

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

importjson

withopen("large-file.json","r")asf:
data=json.load(f)

user_to_repos={}
forrecordindata:
user=record["actor"]["login"]
repo=record["repo"]["name"]
ifusernotinuser_to_repos:
user_to_repos[user]=set()
user_to_repos[user].add(repo)

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

  1. 读取文件
  2. 将生成的字节解码为 Unicode 字符串

9e32edfc-f371-11ec-ba43-dac502259ad0.png

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

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

Python字符串在表示时会被更少使用内存的方法优化。每个字符串都有固定的开销,如果字符串可以表示为 ASCII,则每个字符只使用一个字节的内存。如果字符串使用更多扩展字符,则每个字符可能使用4个字节。我们可以使用 sys.getsizeof() 查看一个对象需要多少内存:

>>>importsys
>>>s="a"*1000
>>>len(s)
1000
>>>sys.getsizeof(s)
1049

>>>s2=""+"a"*999
>>>len(s2)
1000
>>>sys.getsizeof(s2)
2074

>>>s3=""+"a"*999
>>>len(s3)
1000
>>>sys.getsizeof(s3)
4076

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

在本例中我们的大JSON 文件里包含不适合ASCII编码的字符,正是因为它是作为一个巨大的字符串加载的,所以整个巨大的字符串会使用效率较低的内存表示。

流处理解决方案

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

对一个结构为对象列表的 JSON 文件,理论上我们可以一次解析一个块,而不是一次全部解析,以此来减少内存的使用量。目前有许多 Python 库支持这种 JSON 解析方式,下面我们使用 ijson 库来举例。

importijson

user_to_repos={}

withopen("large-file.json","r")asf:
forrecordinijson.items(f,"item"):
user=record["actor"]["login"]
repo=record["repo"]["name"]
ifusernotinuser_to_repos:
user_to_repos[user]=set()
user_to_repos[user].add(repo)

如果使用json标准库,数据一旦被加载文件就会被关闭。而使用ijson,文件必须保持打开状态,因为当我们遍历记录时,JSON 解析器正在按需读取文件。有关更多详细信息,请参阅 ijson 文档。

在内存分析器运行它时,可以发现内存使用的峰值降到了3.6MB,问题解决了!而且在此例子中,使用 ijson 的流式处理也会提升运行时的性能,当然这个性能取决于数据集或算法

9e41e712-f371-11ec-ba43-dac502259ad0.png

其他解决方法

  • Pandas:Pandas 具有读取 JSON 的能力,理论上它可以以更节省内存的方式读取。
  • SQLite:SQLite 数据库可以解析 JSON,将 JSON 存储在列中,以及查询 JSON数据。因此,可以将 JSON 加载到磁盘支持的数据库文件中,并对它运行查询来提取相关的数据子集。

最后,如果可以控制输出格式,则可以通过切换到更高效的表示来减少 JSON 处理的内存使用量。例如,从单个巨大的 JSON 对象列表切换到每行一条 JSON 记录,这意味着每条解码的 JSON 记录将只使用少量内存。

知识延伸

前段时间,Python开发者公号推荐了一款很?实用的 JSON 工具?,可以更轻松直观地查看 JSON。

原文标题:Python 处理超大 JSON 文件,这个方法简单!

文章出处:【微信公众号:Linux爱好者】欢迎添加关注!文章转载请注明出处。

审核编辑:汤梓红
声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 内存
    +关注

    关注

    8

    文章

    3133

    浏览量

    75441
  • python
    +关注

    关注

    56

    文章

    4832

    浏览量

    87751
  • JSON
    +关注

    关注

    0

    文章

    122

    浏览量

    7465

原文标题:Python 处理超大 JSON 文件,这个方法简单!

文章出处:【微信号:LinuxHub,微信公众号:Linux爱好者】欢迎添加关注!文章转载请注明出处。

收藏 人收藏
加入交流群
微信小助手二维码

扫码添加小助手

加入工程师交流群

    评论

    相关推荐
    热点推荐

    什么是反时限过保护?深入解析反时限过保护的应用场景与优势

    在电力系统中,过保护是保障设备安全运行和电网稳定性的重要环节。其中,反时限过保护以其独特的动作特性,在特定应用场景下发挥着不可替代的作用。本文深入探讨反时限过保护的原理、优势,
    的头像 发表于 07-17 13:53 ?484次阅读
    什么是反时限过<b class='flag-5'>流</b>保护?深入<b class='flag-5'>解析</b>反时限过<b class='flag-5'>流</b>保护的应用场景与优势

    技术分享 | 迅为RK3568开发板如何将 Linux 板卡虚拟成U盘

    技术分享 | 迅为RK3568开发板如何将 Linux 板卡虚拟成U盘
    的头像 发表于 06-04 10:57 ?572次阅读
    <b class='flag-5'>技术</b>分享 | 迅为RK3568开发板<b class='flag-5'>如何将</b> Linux 板卡虚拟成U盘

    如何将一个FA模型开发的声明式范式应用切换到Stage模型

    模型切换概述 本文介绍如何将一个FA模型开发的声明式范式应用切换到Stage模型,您需要完成如下动作: 工程切换:新建一个Stage模型的应用工程。 配置文件切换:config.json切换
    发表于 06-04 06:22

    不用联网不用编程,PLC通过智能网关快速实现HTTP协议JSON格式与MES等系统平台双向数据通讯

    进行解析数据写入到PLC,实现PLC与HTTP服务端双向通讯;作为服务端时根据客户端URL中的路径查找所配置的数据,打包成JSON文件后返回给客户端。
    的头像 发表于 05-13 14:40 ?460次阅读
    不用联网不用编程,PLC通过智能网关快速实现HTTP协议<b class='flag-5'>JSON</b>格式与MES等系统平台双向数据通讯

    如何将项目从IAR迁移到Embedded Studio

    本文描述如何将IAR EWARM项目迁移到SEGGER Embedded Studio(简称SES)中。
    的头像 发表于 02-25 17:11 ?679次阅读
    <b class='flag-5'>如何将</b>项目从IAR迁移到Embedded Studio

    k230如何将yolo分类视频推理后的视频结果保存到本地?

    请问k230如何将yolo分类视频推理后的视频结果保存到本地?
    发表于 02-08 08:09

    如何将ADS1278通过SPI与处理器连接?

    在设计电路时,由于采用ADS1278进行8通道同步采样,通过SPI接口与ARM微处理器的SPI接口进行连接,而ADS1278工作在Discrete模式下,请问专家如何将ADS1278通过SPI与处理器连接?此时DOUT1-8如
    发表于 02-07 07:31

    AN3408-如何将12位ADC用于力敏电阻

    电子发烧友网站提供《AN3408-如何将12位ADC用于力敏电阻.pdf》资料免费下载
    发表于 01-21 14:38 ?0次下载
    AN3408-<b class='flag-5'>如何将</b>12位ADC<b class='flag-5'>用于</b>力敏电阻

    如何将FMEA应用于PCB设计第一阶段?

    的每一个环节都充满了挑战和不确定性,稍有不慎就可能引发故障。 为了应对这些挑战,FMEA(Failure Modes and Effects Analysis,即故障模式与效应分析)应用于PCB设计的第一阶段显得尤为重要。FMEA是一种系统化的预防策略,旨在识别和评估产
    的头像 发表于 12-03 11:19 ?766次阅读

    实例篇 4G模组软件之json数据处理

    今天我会把4G模组软件的json数据处理整理成文,以低功耗模组Air780E为例,一一展示出来:
    的头像 发表于 11-12 12:17 ?596次阅读

    控阵列芯片和普通芯片的区别

    控阵列芯片与普通芯片在设计与应用上存在显著差异 设计原理:微控阵列芯片以微米级通道操控流体,集成多种实验功能;普通芯片则通常基于晶体管,用于电子信号处理。 应用领域:微
    的头像 发表于 10-30 15:10 ?821次阅读

    TI TSC应用于各种和多种功能

    电子发烧友网站提供《TI TSC应用于各种和多种功能.pdf》资料免费下载
    发表于 10-22 10:15 ?0次下载
    <b class='flag-5'>将</b>TI TSC<b class='flag-5'>应用于</b>各种和多种功能

    JSON协议是什么,物联网中的RTU中如何使用JSON协议和服务器交互

    一 概述 1.1 什么是 JSON JSON是JavaScript Object Notation的简称,中文含义为“JavaScript 对象表示法”,它是一种数据交换的文本格式,而不是一种编程
    的头像 发表于 09-25 16:14 ?2369次阅读
    <b class='flag-5'>JSON</b>协议是什么,物联网中的RTU中如何使用<b class='flag-5'>JSON</b>协议和服务器交互

    如何将 THVD8000 应用于星型网络系统

    电子发烧友网站提供《如何将 THVD8000 应用于星型网络系统.pdf》资料免费下载
    发表于 09-12 10:36 ?0次下载
    <b class='flag-5'>如何将</b> THVD8000 <b class='flag-5'>应用于</b>星型网络系统

    如何将TRIZ应用于PCB设计的优化阶段?

    随着技术的不断进步和市场竞争的日益激烈,如何高效、创新地优化PCB设计,以降低成本、提升性能、缩短上市周期,成为了工程师们共同面临的挑战。TRIZ(Theory of Inventive
    的头像 发表于 09-04 16:40 ?732次阅读