NPY 格式#
一种用于将 NumPy 数组保存到磁盘并保留其完整信息的简单格式。
.npy 格式是 NumPy 中用于在磁盘上持久化存储单个任意 NumPy 数组的标准二进制文件格式。该格式存储了重建数组所需的所有形状(shape)和数据类型(dtype)信息,即使在具有不同架构的机器上也能正确重建数组。该格式的设计旨在尽可能简单,同时实现其有限的目标。
.npz 格式是用于在磁盘上持久化存储多个 NumPy 数组的标准格式。.npz 文件是一个 zip 文件,其中包含多个 .npy 文件,每个数组对应一个文件。
功能#
可以表示所有 NumPy 数组,包括嵌套记录数组和对象数组。
以原生二进制形式表示数据。
直接支持 Fortran 连续数组。
存储重建数组所需的所有必要信息,包括在不同架构机器上的形状和 dtype。同时支持小端(little-endian)和大端(big-endian)数组,包含小端数字的文件在任何读取该文件的机器上都会产生一个小端数组。类型是根据其各自的实际大小来描述的。例如,如果一台具有 64 位 C “long int” 的机器写出了一个带有 “long ints” 的数组,那么一台具有 32 位 C “long ints” 的读取机器将生成一个 64 位整数的数组。
易于逆向工程。数据集的寿命通常比创建它们的程序更长。一名合格的开发人员应该能够在不查阅过多文档的情况下,使用自己偏好的编程语言创建一个读取大多数已知 .npy 文件的解决方案。
允许对数据进行内存映射(memory-mapping)。请参阅 open_memmap。
可以从类文件流对象(filelike stream object)中读取,而不必是实际的文件。
存储对象数组,即包含任意 Python 对象元素的数组。包含对象数组的文件不能进行内存映射(mmapable),但可以进行磁盘读写。
限制#
numpy.ndarray 的任意子类无法被完全保留。写入时接受子类,但只会写出数组数据。读取文件时将创建一个普通的 numpy.ndarray 对象。
警告
由于对结构化 dtype 的解释存在局限性,名称为空的字段其名称将被替换为 ‘f0’、‘f1’ 等。此类数组通过该格式进行往返转换时无法完全精确。数据是完整的;只有字段名称会有所不同。我们正在研究修复方案。此修复不需要更改文件格式。具有此类结构的数组仍然可以保存和恢复,并且可以通过使用 loadedarray.view(correct_dtype) 方法恢复正确的 dtype。
文件扩展名#
我们建议对以此格式保存的文件使用 .npy 和 .npz 扩展名。这绝非强制要求;应用程序可能希望使用这些文件格式,但使用应用程序特定的扩展名。然而,在没有明显替代方案的情况下,我们建议使用 .npy 和 .npz。
版本编号#
这些格式的版本编号独立于 NumPy 的版本编号。如果格式进行了升级,numpy.io 中的代码仍然能够读取和写入 1.0 版本的文件。
格式版本 1.0#
前 6 个字节是一个魔术字符串(magic string):恰好为 \x93NUMPY。
接下来的 1 个字节是一个无符号字节:文件格式的主版本号,例如 \x01。
接下来的 1 个字节是一个无符号字节:文件格式的次版本号,例如 \x00。注意:文件格式的版本与 numpy 软件包的版本无关。
接下来的 2 个字节构成一个长度为 HEADER_LEN 的小端无符号短整数(unsigned short int),即头部数据的长度。
接下来的 HEADER_LEN 个字节构成了描述数组格式的头部数据。它是一个包含字典 Python 字面量表达式的 ASCII 字符串。它以换行符 (\n) 结尾,并用空格 (\x20) 填充,使得 len(magic string) + 2 + len(length) + HEADER_LEN 的总和能被 64 整除,以实现对齐。
字典包含三个键
“descr”dtype.descr一个可以作为 numpy.dtype 构造函数参数的对象,用于创建数组的 dtype。
“fortran_order”bool数组数据是否为 Fortran 连续。由于 Fortran 连续数组是一种常见的非 C 连续形式,为了效率,我们允许将它们直接写入磁盘。
“shape”tuple of int数组的形状。
为了可重复性和可读性,字典键按字母顺序排序。这仅是为了方便。写入者应尽可能实现这一点。读取者不得依赖此特性。
头部之后是数组数据。如果 dtype 包含 Python 对象(即 dtype.hasobject is True),则数据是数组的 Python pickle 序列化格式。否则,数据是数组的连续字节(根据 fortran_order,可以是 C 连续或 Fortran 连续)。消费者可以通过将形状给出的元素数量(注意 shape=() 表示有 1 个元素)乘以 dtype.itemsize 来计算出总字节数。
格式版本 2.0#
1.0 版本格式仅允许数组头部总大小为 65535 字节。具有大量列的结构化数组可能会超过此限制。2.0 版本格式将头部大小扩展为 4 GiB。numpy.save 在数据需要时会自动以 2.0 格式保存,否则始终使用更具兼容性的 1.0 格式。
因此,头部第四个元素的描述变为:“接下来的 4 个字节构成一个长度为 HEADER_LEN 的小端无符号整数,即头部数据的长度。”
格式版本 3.0#
此版本将 ASCII 字符串(实际上是 latin1)替换为 utf8 编码的字符串,因此支持带有任何 unicode 字段名称的结构化类型。
Notes#
.npy 格式,包括创建它的动机和替代方案的比较,描述在 “npy-format” NEP 中,但细节随时间演变,本文档更为及时。