\n\n### 最新文章\n\n- 如何用ijson在Python中处理大型JSON文件\n- Google开源Harness²:无需重新训练的自我改进AI代理\n- 使用Scikit-LLM进行实体识别:无需重新训练的AI代理技能\n- 2026年成为AI产品经理的路线图\n- 开发者必备的5个Docker容器\n\n## 热门文章\n\n- 开发者必备的5个Docker容器\n- 7个可替代付费订阅的开源AI工具\n- AI软件克隆的兴起:为什么REA和ArtCraft正在病毒式传播\n- AI代理技能的最佳5个GitHub仓库\n- LLM推理工程的5个有趣项目\n- 2026年掌握代理AI系统的路线图\n- Claude Haiku 5.5:新功能及如何用于快速、低成本的AI工作流\n- 2026年可使用的5个免费LLM API提供商\n- 2026年值得关注的10个Hugging Face模型\n- 信任AI生成代码前需要运行的7项检查\n\n#content_wrapper end\n\n© 2026\n\nGuiding Tech Media\n\n|\n\n关于\n\n联系我们\n\n广告合作\n\n隐私政策\n\n服务条款\n\n2026年10月22日由\n\nblank\n\n不,谢谢!\n\n/.main_wrapper\n\n\n\nnoptimize\n\n/noptimize","speakable":{"@type":"SpeakableSpecification","cssSelector":["[data-speakable='summary']","[data-speakable='takeaways']"]},"author":{"@type":"Organization","name":"KDnuggets","url":"https://www.kdnuggets.com"},"publisher":{"@type":"Organization","name":"traeai","url":"https://www.traeai.com","logo":{"@type":"ImageObject","url":"https://www.traeai.com/icon.svg"},"sameAs":["https://github.com/cq0206/traeai"]},"mainEntityOfPage":"https://www.traeai.com/articles/f95af817-cad9-4b9c-9000-fb1b16dde216"},{"@type":"WebSite","@id":"https://www.traeai.com/#website","url":"https://www.traeai.com","name":"traeai","description":"traeai 为开发者、研究员和内容团队筛选高质量 AI 技术内容,提供摘要、评分、趋势雷达与知识库产出。","inLanguage":["zh-CN","en"],"potentialAction":{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https://www.traeai.com/?q={search_term_string}"},"query-input":"required name=search_term_string"}},{"@type":"BreadcrumbList","@id":"https://www.traeai.com/articles/f95af817-cad9-4b9c-9000-fb1b16dde216#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"首页","item":"https://www.traeai.com/"},{"@type":"ListItem","position":2,"name":"文章","item":"https://www.traeai.com/brief"},{"@type":"ListItem","position":3,"name":"KDnuggets","item":"https://www.traeai.com/sources"},{"@type":"ListItem","position":4,"name":"How to Process Large JSON Files in Python With ijson","item":"https://www.traeai.com/articles/f95af817-cad9-4b9c-9000-fb1b16dde216"}]}]}
KDnuggets

How to Process Large JSON Files in Python With ijson

7.1内容质量

TL;DR · AI 摘要

How to Process Large JSON Files in Python With ijson - KDnuggets publ: 22-Oct, 2026 - Blog Top Posts About - Topics AI C...

核心要点

  • 主题聚焦:How to Process Large JSON Files in Python With i
  • 来源:KDnuggets,建议结合原文判断细节。
  • AI 分析暂不可用,本条为保底评分与摘要。
#AI#编程#前端#后端#云计算
打开原文

如何使用 ijson 在 Python 中处理大型 JSON 文件 - KDnuggets

publ: 2026年10月22日

  • 博客热门文章
  • 主题 人工智能 职业建议 计算机视觉 数据工程 数据科学 语言模型 机器学习 MLOps NLP 编程 Python SQL
  • 数据集
  • 活动
  • 资源 快速参考指南 推荐 技术简报
  • 广告

订阅简报

#header end

/ad_wrapper

如何使用 ijson 在 Python 中处理大型 JSON 文件

我在 Python 中加载了一个大型 JSON 文件,发现内存使用量从 43 MB 激增到 808 MB。这里将解释发生了什么,以及流式处理如何彻底改变这一切。

By

Kanwal Mehreen

,KDnuggets 技术编辑兼内容专家,2026年10月22日发布于

人工智能

<div class="addthis_native_toolbox"></div>

JSON 是 Python 应用程序中存储和交换数据最常用的格式之一。对于小文件,Python 内置的 json 模块工作效果很好:

code
import json

with open("data.json") as f:
    data = json.load(f)

当文件变得很大时就会出现问题。

json.load() 会解析整个 JSON 文档,并在开始处理数据之前在内存中创建对应的 Python 对象。因此,一个在磁盘上仅占用几百兆字节的文件,在转换为 Python 字典、列表、字符串和数字后,可能需要消耗大量内存。

对于这种类型的工作负载,更好的选择是 ijson ,这是一个迭代式 JSON 解析器,允许您逐步处理数据。在本教程中,我们将使用包含旧金山土地地块数据的大型 JSON 文件。我们首先使用 json.load() 处理它,测量内存变化,然后使用 ijson 解决相同任务。

第一步:下载大型 JSON 数据集

为了这次实验,我们将使用旧金山城市地块数据集。我在这篇文章中使用 Google Colab。使用以下命令下载:

code
curl -L 
https://raw.githubusercontent.com/zemirco/sf-city-lots-json/master/citylots.json 
-o citylots.json

可以使用以下命令检查其大小:

code
ls -lh citylots.json

该数据集大小为 181 MB,足够大以展示加载和流式处理 JSON 之间的差异。文件遵循标准的 GeoJSON FeatureCollection 结构。可以使用以下代码检查:

code
import json

with open("citylots.json", "r") as f:
    data = json.load(f)

print(data.keys())
data["features"][0]

输出:

code
dict_keys(['type', 'features'])

{'type': 'Feature',
 'properties': {'MAPBLKLOT': '0001001',
  'BLKLOT': '0001001',
  'BLOCK_NUM': '0001',
  'LOT_NUM': '001',
  'FROM_ST': '0',
  'TO_ST': '0',
  'STREET': 'UNKNOWN',
  'ST_TYPE': None,
  'ODD_EVEN': 'E'},
 'geometry': {'type': 'Polygon',
  'coordinates': [[[-122.42200352825247, 37.80848009696725, 0.0],
    [-122.42207601332528, 37.808835019815085, 0.0],
    [-122.42110217434863, 37.808803534992904, 0.0],
    [-122.42106256906727, 37.80860105681815, 0.0],
    [-122.42200352825247, 37.80848009696725, 0.0]]]}}

对我们来说,重要的部分是 features 数组。

每个 feature 代表一个地块,包含两个主要部分:

code
feature
├── properties
│   ├── BLKLOT
│   ├── BLOCK_NUM
│   ├── LOT_NUM
│   └── STREET
│
└── geometry
    └── coordinates

我们的分析只需要 properties 下的几个值。然而,如果我们使用标准 JSON 解析器,Python 仍然必须加载所有 geometry 坐标。

第二步:使用 json.load() 处理文件

让我们先使用大多数 Python 开发者会自然尝试的方法。创建一个名为 standard_json.py 的文件:

code
import json
import time

start = time.perf_counter()

with open("citylots.json", "r") as f:
    data = json.load(f)

features = data["features"]

market_count = 0
first_five = []

for feature in features:

    properties = feature["properties"]

    if properties.get("STREET") == "MARKET":

        market_count += 1

        if len(first_five) < 5:
            first_five.append(
                properties.get("BLKLOT")
            )

elapsed = time.perf_counter() - start

print(f"Total parcels: {len(features):,}")
print(f"Market Street parcels: {market_count:,}")
print(f"First five parcel IDs: {first_five}")
print(f"Time: {elapsed:.2f} seconds")

这段代码简单且完全有效。

问题出在这行代码:

code
data = json.load(f)

在我们的循环可以处理任何一块数据之前,Python 必须:

code
读取整个文件
        ↓
解析每个 JSON 对象
        ↓
创建所有 Python 字典
        ↓
创建所有列表和坐标
        ↓
将所有内容存储在内存中
        ↓
开始分析

这意味着即使我们只需要 STREET 和 BLKLOT 字段,也会加载数据集中的所有多边形和坐标。这是我得到的输出结果:

code
Total parcels: 206,560
Market Street parcels: 808
First five parcel IDs: ['0265003', '0265004', '0265005', '0290012', '0291001']
Time: 4.01 seconds

第三步:测量内存使用情况

与其简单地说 json.load() 消耗大量内存,不如直接进行测量。

一个简单的选择是使用 memory-profiler 库。

安装方法:

code
pip install memory-profiler

现在将代码替换为以下内容:

code
from memory_profiler import profile
import json

@profile
def process_file():

    with open("citylots.json", "r") as f:
        data = json.load(f)

    features = data["features"]

    market_count = 0

    for feature in features:

        if (
            feature["properties"]
            .get("STREET") == "MARKET"
        ):
            market_count += 1

process_file()

运行命令:

code
python -m memory_profiler standard_json.py

需要重点关注的行是 data = json.load(f) :

code
行号    内存使用量    增量    出现次数    代码行内容
=============================================================
     5     43.4 MiB     43.4 MiB           1   @profile
     6                                         def process_file():
     7                                     
     8    808.9 MiB      0.0 MiB           2       with open("citylots.json", "r") as f:
     9    808.9 MiB    765.5 MiB           1           data = json.load(f)
    10                                     
    11    808.9 MiB      0.0 MiB           1       features = data["features"]
    12                                     
    13    808.9 MiB      0.0 MiB           1       market_count = 0
    14                                     
    15    808.9 MiB      0.0 MiB      206561       for feature in features:
    16                                     
    17                                                 if (
    18    808.9 MiB      0.0 MiB      413120               feature["properties"]
    19    808.9 MiB      0.0 MiB      206560               .get("STREET") == "MARKET"
    20                                                 ):
    21    808.9 MiB      0.0 MiB         808               market_count += 1
    22                                     
    23    808.9 MiB      0.0 MiB           1       print("Total parcels:", len(features))
    24    808.9 MiB      0.0 MiB           1       print("Market Street parcels:", market_count)

此时可以明显看到内存消耗的显著增加。

为什么内存使用量可能远大于原始 JSON 文件?

因为像这样的 JSON:

code
{
  "STREET": "MARKET"
}

在解析后会变成多个 Python 对象:

code
字典
   ↓
Python 字符串键
   ↓
Python 字符串值

嵌套的几何数组和数值坐标也会发生同样的情况。

因此,文件在磁盘上的大小与解析后的内存占用是不一致的。

这为我们提供了与 ijson 对比的基准。

第 4 步:使用 ijson 流式处理 JSON 文件

现在让我们在不加载完整文档的情况下解决同样的问题。

安装 ijson:

code
pip install ijson

我们将使用的关键函数是:

code
ijson.items()

我们的数据集具有以下层次结构:

code
root
│
├── type
│
└── features
     ├── item
     ├── item
     ├── item
     └── ...

因此,我们可以要求 ijson 逐个返回每个 feature:

code
import ijson

with open("citylots.json", "rb") as f:

    for feature in ijson.items(
        f,
        "features.item"
    ):

        print(feature)
        break

前缀:

code
features.item

表示:

进入 features 数组并返回其中的每个元素。

ijson 不会创建一个巨大的 parcels 列表,而是逐个提供记录。

概念上:

code
Feature 1
   ↓
处理
   ↓
丢弃

Feature 2
   ↓
处理
   ↓
丢弃

Feature 3
   ↓
处理
   ↓
丢弃

这会显著改变内存需求。

第 5 步:使用 ijson 执行相同分析

现在让我们重复执行完全相同的任务。

创建 stream_json.py:

code

import ijson import time

start = time.perf_counter()

total = 0 market_count = 0 first_five = []

with open("citylots.json", "rb") as f:

for feature in ijson.items( f, "features.item" ):

total += 1

properties = feature["properties"]

if properties.get("STREET") == "MARKET":

market_count += 1

if len(first_five) < 5: first_five.append( properties.get("BLKLOT") )

elapsed = time.perf_counter() - start

print(f"Total parcels: {total:,}") print(f"Market Street parcels: {market_count:,}") print(f"First five parcel IDs: {first_five}") print(f"Time: {elapsed:.2f} seconds")

code

Total parcels: 206,560 Market Street parcels: 808 First five parcel IDs: ['0265003', '0265004', '0265005', '0290012', '0291001'] Time: 4.58 seconds

code

我们不再需要:

或:

features = data["features"]

code

而是由程序直接从解析器处理每个要素:

for feature in ijson.items( f, "features.item" ):

code

在任何时刻,我们主要需要内存存储:

当前要素 + ijson解析器缓冲区 + 小型计数器 + 五个保存的ID

code

我们不需要为完整数据集分配内存。

运行相同的内存测试:

Line # Mem usage Increment Occurrences Line Contents ============================================================= 5 43.8 MiB 43.8 MiB 1 @profile 6 def process_file(): 7 8 43.8 MiB 0.0 MiB 1 total = 0 9 43.8 MiB 0.0 MiB 1 market_count = 0 10 11 46.1 MiB 0.0 MiB 2 with open("citylots.json", "rb") as f: 12 13 46.1 MiB 2.2 MiB 206562 for feature in ijson.items( 14 43.8 MiB 0.0 MiB 1 f, 15 43.8 MiB 0.0 MiB 1 "features.item" 16 ): 17 18 46.1 MiB 0.0 MiB 206560 total += 1 19 20 if ( 21 46.1 MiB 0.1 MiB 413120 feature["properties"] 22 46.1 MiB 0.0 MiB 206560 .get("STREET") == "MARKET" 23 ): 24 45.8 MiB 0.0 MiB 808 market_count += 1 25 26 27 46.1 MiB 0.0 MiB 1 print("Total parcels:", total) 28 46.1 MiB 0.0 MiB 1 print("Market Street parcels:", market_count)

code

现在将峰值内存使用量与 json.load() 的结果进行对比。

方法对比

输入文件

峰值内存

处理方式

json.load()

code

181 MB

808.9 MiB

加载全部数据

46.1 MiB

流式处理记录

差异

相同文件

约少使用 762.8 MiB 内存

更高效的处理方式

重要行为应保持一致:ijson 主要优势在于这种更稳定的内存占用特征。

这并不意味着ijson在所有情况下都会更快。当可用RAM充足时,json.load()有时可以非常快速地解析文档。ijson的主要优势在于,内存消耗不再需要随着完整JSON文档的大小而增长。

## 总结

大型JSON文件并不一定需要消耗大量内存。

问题往往不在于JSON格式本身,而在于我们选择处理它的方式。

在本教程中,我们使用了一个约181MB的真实旧金山土地地块数据集。

使用Python标准库:

json.load(f)

code

必须将整个数据集解析为Python对象后,分析才能开始。

这包括数千个嵌套的字典、列表、属性值、多边形和坐标,而这些内容我们的特定任务甚至根本不需要。

使用:

ijson.items( f, "features.item" )

code

彻底改变了处理模式。

我们不再采用:

加载所有内容 → 处理

code

而是使用:

读取 → 处理 → 丢弃

code

关键要点很简单:

> 如果你的任务只需要每次处理一条记录,通常没有理由一次性加载所有记录。

Kanwal Mehreen 是一名机器学习工程师和技术作家,对数据科学以及人工智能与医学的交叉领域充满热情。她合著了电子书《用ChatGPT最大化生产力》。作为2022年APAC地区Google Generation学者,她倡导多样性和学术卓越。她还被认定为Teradata科技多样性学者、Mitacs Globalink研究学者和哈佛WeCode学者。Kanwal是变革的坚定倡导者,她创立了FEMCodes组织,致力于赋能STEM领域的女性。

### 更多相关内容

- 数据科学生命周期流程
- 如何用Python清理杂乱的CSV文件:初学者指南
- 如何用Python写入文件:初学者指南
- 用Python的Pathlib组织、搜索和备份文件
- 如何在Bash中管理文件和目录
- 5个有用的DIY Python函数用于JSON解析和处理

<hr class="grey-line"><br> <div><h3>我们推荐的5门免费课程</h3><br> </div>

Mailchimp for WordPress v4.14.1 - https://wordpress.org/plugins/mailchimp-for-wp/

/ Mailchimp for WordPress插件

你可以从这里开始编辑。

如果评论已关闭。

<= 上一篇

#content end

<script type="text/javascript">kda_sid_write(kda_sid_n);</script>

### 最新文章

- 如何用ijson在Python中处理大型JSON文件
- Google开源Harness²:无需重新训练的自我改进AI代理
- 使用Scikit-LLM进行实体识别:无需重新训练的AI代理技能
- 2026年成为AI产品经理的路线图
- 开发者必备的5个Docker容器

## 热门文章

- 开发者必备的5个Docker容器
- 7个可替代付费订阅的开源AI工具
- AI软件克隆的兴起:为什么REA和ArtCraft正在病毒式传播
- AI代理技能的最佳5个GitHub仓库
- LLM推理工程的5个有趣项目
- 2026年掌握代理AI系统的路线图
- Claude Haiku 5.5:新功能及如何用于快速、低成本的AI工作流
- 2026年可使用的5个免费LLM API提供商
- 2026年值得关注的10个Hugging Face模型
- 信任AI生成代码前需要运行的7项检查

#content_wrapper end

© 2026

Guiding Tech Media

|

关于

联系我们

广告合作

隐私政策

服务条款

2026年10月22日由

blank

不,谢谢!

/.main_wrapper

<script defer type="text/javascript" src="https://s7.addthis.com/js/300/addthis_widget.js#pubid=gpsaddthis"></script>

noptimize

/noptimize