Jupyter运行变慢的根源在于环境状态臃肿而非代码本身:内核重放上下文、大体积JSON文件解析卡顿、输出缓存堆积、内存未及时释放及notebook过度膨胀;应清空outputs、降低绘图分辨率、主动del+gc.collect()、按数据流拆分并导出为.py脚本。

不是代码本身慢,而是 Jupyter 的执行环境和状态在拖慢你——尤其当你反复修改、运行、再修改同一个单元格时。
为什么改一行代码就要等十几秒?
这不是 Python 解释器慢,是 Jupyter 内核在「重放整个上下文」:它保留了所有变量、历史命令、输出缓存,甚至已加载的模块状态。哪怕你只改了 df.head(5) 为 df.head(10),内核仍要重新序列化/反序列化大量对象、检查依赖、重建输出结构。
- 典型表现:首次运行快,改完再运行巨慢;
.ipynb文件体积超过 50MB 后打开/保存明显卡顿 - 根本原因:VS Code 或 JupyterLab 前端对大型 JSON(.ipynb 文件本质)的解析和渲染开销,远超代码执行本身
- 容易被忽略的一点:
%matplotlib inline渲染高清图后,图片 base64 编码直接塞进 JSON,一个 2MB 图片会让文件膨胀 3MB+
删掉 output 和 execution_count 再试一次
绝大多数“运行变慢”问题,其实卡在前端加载旧输出上,而不是执行代码。清空这些字段能立竿见影:
- 在 VS Code 中:右键单元格 → Clear Output;或全选所有单元格 →
Ctrl+Shift+P→ 输入 “Jupyter: Clear All Outputs” - 手动清理文件:用文本编辑器打开
.ipynb,删掉所有"outputs": [...]和"execution_count": N字段(保留"source"和"cell_type"即可) - 加个保险:在 notebook 开头加
%config InlineBackend.rc = {'figure.dpi': 96},降低默认绘图分辨率,避免生成巨型 PNG
del + gc.collect() 不是可选项,是必做动作
Jupyter 内核不会自动释放你不再需要的大对象——比如读完 CSV 后的 df、训练完的 model、中间生成的 plt.figure()。它们一直占着内存,让后续 GC 更吃力。
- 别只靠重启内核:频繁重启会丢失调试上下文,且无法解决底层内存碎片
- 写完分析立刻清理:
del df, model, fig,然后紧跟import gc; gc.collect() - 注意陷阱:
del只删引用,如果对象被其他变量、闭包、全局字典间接持有,依然不释放;可用sys.getrefcount(obj)检查引用数 - 更狠一招:在关键步骤后执行
%reset -f(清除所有变量),但需确保你没依赖前面定义的函数或类
别让 notebook 自己“长大”,拆或导出是常态
一个 200 行、含 10 个图表、3 次模型训练的 notebook,本质上已是不可维护的“单体脚本”。它不只是慢,还会在协作、版本控制、CI/CD 中持续制造麻烦。
- 拆分原则:按数据流阶段切,比如
01_load_clean.ipynb、02_featurize.ipynb、03_train_eval.ipynb - 导出为 .py:用
jupyter nbconvert --to python notebook.ipynb,把稳定逻辑转成可测试、可 profile 的脚本 - 保留探索性 notebook:只放临时分析、可视化调试、参数试错——并定期清空输出、压缩图片、删掉注释掉的旧代码块
真正卡住你的,往往不是某行代码效率低,而是 notebook 已经变成一个臃肿的状态容器。优化不是调参,是主动管理它的生命周期。


















