savez不压缩而savez_compressed启用ZIP_DEFLATED压缩;键名须为合法Python标识符,否则报错;读取需用npz.files查看键列表,不可调用.keys();高熵数据压缩反而更慢更大。

savez 本身不压缩,真正压缩靠的是 savez_compressed —— 直接用 savez 存出来的 .npz 文件是未压缩的,体积和多个单独 .npy 文件加起来差不多。
savez 和 savez_compressed 的核心区别在哪?
两者接口几乎一样,但底层行为不同:
-
savez把每个数组按np.save方式写入 zip 容器,不启用 zip 压缩(即compress_type=zipfile.ZIP_STORED) -
savez_compressed显式使用zipfile.ZIP_DEFLATED,对每个数组单独压缩 - 压缩效果高度依赖数据类型和重复模式:浮点数组(尤其含大量零或相近值)压缩率高;随机 uint8 图像数据可能只减小 10–30%;而已经压缩过的数据(如 JPEG 解码后的 ndarray)再压基本无效
怎么避免 savez_compressed 写入后读不出来?
常见错误是误以为 .npz 文件像字典一样支持任意键名访问,其实它只认合法的 Python 标识符作为 key:
安全 Python 代码沙箱:在隔离的沙箱中执行任意 Python 代码,预装 requests、NumPy、pandas 库。返回 stdout、stderr。
- 键名不能以数字开头(
savez_compressed('a.npz', '1array'=arr)→ 报错SyntaxError) - 键名不能含空格、连字符、点号等(
'my-array'、'data.0'都非法) - 推荐做法:统一用下划线命名,例如
savez_compressed('model.npz', weights=arr1, biases=arr2) - 如果必须用动态键名,先校验:
key.isidentifier() and not keyword.iskeyword(key)
读取时为什么 arr['unknown_key'] 报 KeyError 而不是提示可用 key?
np.load() 返回的是 numpy.lib.npyio.NpzFile 对象,它懒加载且不暴露完整 keys 列表直到你主动查:
立即学习“Python免费学习笔记(深入)”;
- 正确查键方式:
npz = np.load('data.npz'); print(npz.files)—— 输出是 list,如['weights', 'biases'] - 别用
list(npz.keys()),因为NpzFile没有.keys()方法(会 AttributeError) - 如果存的时候用了中文或非法名(比如通过
**dict动态传参但没清洗),npz.files里会出现乱码或不可见字符,需用repr(npz.files)查看真实字符串
压缩不是万能的——高熵数据(比如加密后的 float64 数组)用 savez_compressed 可能比 savez 更慢且文件更大。实际保存前,建议先对典型样本跑个 timeit + os.path.getsize 对比。

















