np.savez 不压缩数据,文件大小≈各数组 .npy 之和;改用 np.savez_compressed 可启用 ZIP_DEFLATED 压缩,压缩率取决于数据特征,懒加载可避免内存暴涨。

np.savez 打包后文件为什么没变小?
因为 np.savez 默认用的是无压缩的 ZIP 存档,只是把多个数组塞进一个 .npz 文件里,不压缩数据本身。你看到的文件大小基本等于各数组 .npy 文件大小之和。
实操建议:
让 macOS 自动化像说话一样简单 —— 用代码控制你的 Mac,无需学习 AppleScript 系统要求 macOS 14+ (Sonoma) Python 3.9+ 需要开启:辅助功能 + 屏幕录制权限
- 改用
np.savez_compressed—— 它默认启用 ZIP_DEFLATED 压缩,对重复值多、含大量零或低精度浮点的数组效果明显 - 压缩率取决于数据内容:随机 float64 数组压缩比通常不到 1.2x;量化后的 uint8 图像或稀疏矩阵可能压到 1/3 大小
- 别对单个小数组(比如 shape=(100,))用
np.savez_compressed,ZIP 包装头开销反而让文件更大
保存时怎么控制不同数组的压缩级别?
np.savez_compressed 不支持 per-array 压缩参数,整个 .npz 是统一压缩的。但你可以手动拆解:先用 np.save 把每个数组单独存成 .npy,再用 Python 标准库 zipfile 按需设置 compresslevel 打包。
常见错误现象:试图传 compresslevel=9 给 np.savez_compressed 会报 TypeError: savez_compressed() got an unexpected keyword argument。
立即学习“Python免费学习笔记(深入)”;
实操建议:
- 需要差异化压缩 → 改用
zipfile.ZipFile+numpy.ndarray.tobytes()+zipfile.ZIP_DEFLATED - 想保留 numpy 的读取便利性 → 用
np.savez_compressed就够了,它内部已用compresslevel=6,平衡速度与压缩率 - 注意:压缩级别只影响 CPU 时间,不影响读取兼容性 —— 所有 Python + numpy 环境都能正常
np.load()解压后的 .npz
加载 npz 文件时内存暴涨,怎么避免?
np.load("data.npz") 返回的是 numpy.lib.npyio.NpzFile 对象,它懒加载 —— 只有你真正访问 npz["arr_0"] 或调用 npz.files 时才读入对应数组。但很多人直接写 dict(npz) 或 [npz[k] for k in npz.files],这就强制全量加载,内存瞬间拉满。
实操建议:
- 按需索引:只写
npz["image"]或npz["label"],别一口气转成 dict 或 list - 检查键名再读:先用
npz.files看有哪些数组名,确认你要的字段存在,再取 - 大数组场景下,考虑用
np.memmap配合解压后的 .npy 文件,而不是硬扛整个 .npz 到内存
np.savez 和 np.savez_compressed 的兼容性差异
两者生成的都是标准 ZIP 格式 .npz 文件,np.load() 能无缝读取,没有运行时兼容问题。真正的差异在 Python 版本和 numpy 版本的底层 ZIP 实现上。
容易踩的坑:
- Python zipfile 默认不支持 LZMA,但
np.savez_compressed不用 LZMA,所以没问题 - 极老的 numpy(
- 如果你用
np.savez存了空数组(np.array([])),某些旧版本 numpy(ValueError: cannot reshape array;加_compressed版本更稳
实际项目中,只要 numpy ≥ 1.19、Python ≥ 3.7,直接无脑用 np.savez_compressed 更省心。压缩本身不增加 IO 延迟太多,但省下的磁盘空间和网络传输时间往往值得这点 CPU 开销。

















