我们相信:世界是美好的,你是我也是。平行空间的世界里面,不同版本的生活也在继续...

上一篇文章分析的是.npy文件,苏南大叔在本文里面来分析一下.npz文件。苏南大叔觉得两者的最大区别就是:.npy保存的是某个单一变量值,而.npz保存的是多个变量。本文主要表述的主体还是.npz文件。

苏南大叔:基于python,numpy库如何生成npz文件?如何解析? - numpy-npz
基于python,numpy库如何生成npz文件?如何解析?(图2-1)

苏南大叔的“程序如此灵动”博客,记录苏南大叔和计算机代码的故事。本文测试环境:win10python@3.12.0numpy@1.26.1.savez().load()都是有好多参数的,但是本文里面并不都做展示,因为用不到。

前文回顾

回顾一下numpy.npy文件进行操作的文章,可能可以会更好的理解本文的文章。

类型生成解析
.npy.save().load()
.npz.savez().load()

生成.npz文件

import numpy as np
s1 = np.array([["苏", "南", "大", "叔"]])    # ndarray
s2 = ["苏", "南", "大", "叔"]                # list
s3 = ("苏", "南", "大", "叔")                # tuple
s4 = {"苏", "南", "大", "叔"}                # set
s5 = {"s":"苏","n":"南","d":"大","s2":"叔"}  # dict
s6 = "苏南大叔"                              # str
s7 = 168                                    # int
s8 = range(0,3)                             # range
np.savez("test.npz", s1, s2, s3, s4, s5, s6, s7, s8)

这里的文件保存函数是np.savez(),注意不是np.save()。当然,也可以使用.savez_compressed()

np.savez_compressed("test.npz", s1, s2, s3, s4, s5, s6, s7, s8)

区别,目前来看就是:最后生成文件的体积大小。

函数是否压缩处理数据
np.save()不压缩单条数据
np.savez()不压缩仅打包单条或多条
np.savez_compressed()打包加压缩单条或多条

解析.npz文件

n = np.load("test.npz",allow_pickle=True)
print(n,type(n))                            
# NpzFile 'test.npz' with keys: arr_0, arr_1, arr_2, arr_3, arr_4... <class 'numpy.lib.npyio.NpzFile'>

print(n.files)              # ['arr_0', 'arr_1', 'arr_2', 'arr_3', 'arr_4', 'arr_5', 'arr_6', 'arr_7']
print(n['arr_0'])           # [['苏' '南' '大' '叔']]

for key, arr in n.items():
  print(key, ": ", arr, type(arr))
'''
arr_0 :  [['苏' '南' '大' '叔']] <class 'numpy.ndarray'>
arr_1 :  ['苏' '南' '大' '叔'] <class 'numpy.ndarray'>
arr_2 :  ['苏' '南' '大' '叔'] <class 'numpy.ndarray'>
arr_3 :  {'苏', '叔', '大', '南'} <class 'numpy.ndarray'>
arr_4 :  {'s': '苏', 'n': '南', 'd': '大', 's2': '叔'} <class 'numpy.ndarray'>
arr_5 :  苏南大叔 <class 'numpy.ndarray'>
arr_6 :  168 <class 'numpy.ndarray'>
arr_7 :  [0 1 2] <class 'numpy.ndarray'>
'''

设置files索引名称

np.load()的时候,解析出来的.files的键名,也是可以定义的。看看下面的代码有何区别?

import numpy as np
s1 = np.array([["苏", "南", "大", "叔"]])    # ndarray
s2 = ["苏", "南", "大", "叔"]                # list
s3 = ("苏", "南", "大", "叔")                # tuple
s4 = {"苏", "南", "大", "叔"}                # set
s5 = {"s":"苏","n":"南","d":"大","s2":"叔"}  # dict
s6 = "苏南大叔"                              # str
s7 = 168                                    # int
s8 = range(0,3)                             # range
np.savez("test.npz", s1=s1, s2=s2, s3=s3, s4=s4, s5=s5, s6=s6, s7=s7, s8=s8)  # 【区别在这里】

n = np.load("test.npz",allow_pickle=True)
print(n.files)                              # ['s1', 's2', 's3', 's4', 's5', 's6', 's7', 's8']
for key, arr in n.items():
  print(key, ": ", arr, type(arr))
'''
s1 :  [['苏' '南' '大' '叔']] <class 'numpy.ndarray'>
s2 :  ['苏' '南' '大' '叔'] <class 'numpy.ndarray'>
s3 :  ['苏' '南' '大' '叔'] <class 'numpy.ndarray'>
s4 :  {'叔', '南', '大', '苏'} <class 'numpy.ndarray'>
s5 :  {'s': '苏', 'n': '南', 'd': '大', 's2': '叔'} <class 'numpy.ndarray'>
s6 :  苏南大叔 <class 'numpy.ndarray'>
s7 :  168 <class 'numpy.ndarray'>
s8 :  [0 1 2] <class 'numpy.ndarray'>
'''

.close()

这是个文件读取的操作,所以必然存在着一个.close()操作。

# 注意这个 `.close()` 操作
n.close()

print(n.files)                              # ['s1', 's2', 's3', 's4', 's5', 's6', 's7', 's8']
for key, arr in n.items():                  # AttributeError: 'NoneType' object has no attribute 'open'
  print(key, ": ", arr, type(arr))

close()之后,再试图读取其内容的话,就可能会出现下面的错误提示信息了。

    bytes = self.zip.open(key)
            ^^^^^^^^^^^^^
AttributeError: 'NoneType' object has no attribute 'open'

那么,什么时候执行.close()呢?那必然是

  • 不再需要对.load()结果进行解析的时候,主动执行.close()。【推荐】
  • 或者不主动执行,等逻辑自然完成,再去回收资源。

可能存在的问题

ValueError: Object arrays cannot be loaded when allow_pickle=False

因为这里有表现形式为{}set类型和dict类型保存到了文件之中,所以使用.load()来解析文件的时候,需要设置allow_pickle=True

n = np.load("test.npz",allow_pickle=True)

一个可能的真相

.npz文件可能就是个zip文件,如果把文件名里面的后缀npz修改为zip或者rar的话,就可以使用压缩软件打开,然后看到对应的一系列file.npy文件。

苏南大叔:基于python,numpy库如何生成npz文件?如何解析? - 压缩软件解析npz文件
基于python,numpy库如何生成npz文件?如何解析?(图2-2)

结语

苏南大叔的更多python文章,请点击苏南大叔的博客文章:

如果本文对您有帮助,或者节约了您的时间,欢迎打赏瓶饮料,建立下友谊关系。
本博客不欢迎:各种镜像采集行为。请尊重原创文章内容,转载请保留作者链接。

 【福利】 腾讯云最新爆款活动!1核2G云服务器首年50元!

 【源码】本文代码片段及相关软件,请点此获取更多信息

 【绝密】秘籍文章入口,仅传授于有缘之人   python