在速度,内存和查找方面,在Python中保存`.npz`文件而不是`.npy`有什么好处?

Sup*_*cia 3 python file-io serialization numpy save

用于numpy.savez保存.npz文件的python文档为:

.npz文件格式是以文件包含的变量命名的压缩文件存档。档案未压缩,档案中的每个文件都包含一个.npy格式的变量。[...]

在加载时打开保存的.npz文件时,将返回NpzFile对象。这是一个类似于字典的对象,可以查询其数组列表(带有.files属性)以及数组本身。

我的问题是:有什么意义numpy.savez

是只是保存多个数组的更优雅的版本(更短的命令),还是在保存/读取过程中加快了速度?它占用更少的内存吗?

use*_*699 10

主要优点是数组是延迟加载的。也就是说,如果您有一个npz包含 100 个数组的文件,您可以加载该文件而无需实际加载任何数据。如果您请求单个数组,则仅加载该数组的数据。

文件的一个缺点npz是它们无法进行内存映射(使用load(<file>, mmap_mode='r')),因此对于大型数组来说它们可能不是最佳选择。对于数组具有共同形状的数据,我建议查看结构化数组。这些可以是内存映射的,允许使用类似字典的语法(即arr['field'])访问数据,并且在内存方面非常高效。

  • 但是,将 100 个数组保存为 100 个 .npy 数组并仅加载我想要的数组,将它们保存为 1 .npz 文件并请求其中一个数组有什么区别? (3认同)
  • @SuperCiocia 添加了 @Eureka 的评论,我想补充一点,`.npz` 格式相对于单个文件基本上有 2 个优点。第一:所有存储的子数组都在标头中建立索引,这使得对多个数组进行随机读取比查询每个文件的文件系统索引更快。其次,正如@Eureka所说,如果你有很多小文件,移动它们或批量更新会快得多。但是,如果您始终只需要特定上下文中的单个数组,或者想要执行大量无法批量进行的单独更新,则最好使用单个文件。 (2认同)

YaO*_*OzI 5

回答问题有两个解释部分。

I.NPY与NPZ

正如我们已经从文档中读取的那样,.npy格式为:

NumPy中的标准二进制文件格式,用于将单个任意NumPy数组持久存储在磁盘上。...该格式旨在在达到其有限目标的同时尽可能地简单。(来源

而且.npz只是一个

多个数组组合成一个文件的一种简单方法,可以使用ZipFile包含多个“ .npy”文件。.npz对于这些档案,我们建议使用文件扩展名“ ”。(来源

因此,.npzZipFile只是包含多个“ .npy”文件。并且此ZipFile可以压缩(通过使用np.savez_compressed)或未压缩(通过使用np.savez

它类似于压缩包档案文件中的类Unix系统,其中压缩包文件可以只是通过与各种压缩程序组合含有其他文件或压缩存档文件的未压缩存档文件(gzipbzip2等)

二。二进制序列化的不同API

Numpy还提供了不同的API来生成这些二进制文件输出:

  • np.save--->将数组保存为NumPy .npy格式的二进制文件
  • np.savez->将多个数组以未压缩的 .npz格式保存到单个文件中
  • np.savez_compressed->将多个数组以压缩 .npz格式保存到单个文件中
  • np.load->从中加载数组或腌制的对象.npy.npz或腌制的文件

如果我们撇去numpy的源代码,在引擎盖下,主要有:

def _savez(file, args, kwds, compress, allow_pickle=True, pickle_kwargs=None):
    ...
    if compress:
        compression = zipfile.ZIP_DEFLATED
    else:
        compression = zipfile.ZIP_STORED
    ...


def savez(file, *args, **kwds):
    _savez(file, args, kwds, False)


def savez_compressed(file, *args, **kwds):
    _savez(file, args, kwds, True)
Run Code Online (Sandbox Code Playgroud)

然后回到问题:

如果仅使用np.save,则.npy格式顶部将没有更多压缩,只有一个存档文件可方便管理多个相关文件。

如果使用np.savez_compressed,那么磁盘上的内存当然会减少,因为执行压缩作业需要更多的CPU时间(即,速度稍慢)。