基于python,numpy库如何生成npz文件?如何解析?
发布于 作者:苏南大叔 来源:程序如此灵动~ 我们相信:世界是美好的,你是我也是。平行空间的世界里面,不同版本的生活也在继续...
上一篇文章分析的是.npy
文件,苏南大叔在本文里面来分析一下.npz
文件。苏南大叔觉得两者的最大区别就是:.npy
保存的是某个单一变量值,而.npz
保存的是多个变量。本文主要表述的主体还是.npz
文件。
苏南大叔的“程序如此灵动”博客,记录苏南大叔和计算机代码的故事。本文测试环境:win10
,python@3.12.0
,numpy@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
文章,请点击苏南大叔的博客文章:
如果本文对您有帮助,或者节约了您的时间,欢迎打赏瓶饮料,建立下友谊关系。
本博客不欢迎:各种镜像采集行为。请尊重原创文章内容,转载请保留作者链接。
本博客不欢迎:各种镜像采集行为。请尊重原创文章内容,转载请保留作者链接。