numpy.lib.format#

二进制序列化

NPY 格式#

一种简单的格式,用于将 numpy 数组及其所有信息保存到磁盘。

`.npy` 格式是 NumPy 中将*单个*任意 NumPy 数组持久化到磁盘的标准二进制文件格式。该格式存储了重建数组所需的所有形状和 dtype 信息,即使在具有不同架构的另一台机器上也能正确重建。该格式设计得尽可能简单,同时实现其有限的目标。

`.npz` 格式是将*多个* NumPy 数组持久化到磁盘的标准格式。`.npz` 文件是一个 zip 文件,其中包含多个 `.npy` 文件,每个文件对应一个数组。

功能#

  • 可以表示所有 NumPy 数组,包括嵌套记录数组和对象数组。

  • 以其原生二进制形式表示数据。

  • 直接支持 Fortran 顺序数组。

  • 存储了重建数组所需的所有信息,包括在不同架构的机器上重建数组的形状和 dtype。支持小端和大端数组,并且在一个包含小端数字的文件中,无论在哪台机器上读取该文件,都会得到一个小端数组。类型根据其实际大小进行描述。例如,如果一台具有 64 位 C “long int”的机器写入了一个包含“long int”的数组,那么在一台具有 32 位 C “long int”的读取机器上,将会得到一个包含 64 位整数的数组。

  • 易于逆向工程。数据集的生命周期通常比创建它们程序要长。一个有能力的开发人员应该能够用他们喜欢的编程语言创建解决方案,以读取他们收到的绝大多数 `.npy` 文件,而无需太多文档。

  • 允许对数据进行内存映射。请参阅 open_memmap

  • 可以从类文件流对象而不是实际文件读取。

  • 存储对象数组,即包含任意 Python 对象元素的数组。包含对象数组的文件不能进行内存映射,但可以读写到磁盘。

限制#

  • numpy.ndarray 的任意子类不会被完全保留。子类将被接受写入,但只会写出数组数据。读取文件时会创建一个普通的 numpy.ndarray 对象。

警告

由于结构化 dtype 的解释限制,字段名称为空的 dtype 的名称将被替换为“f0”、“f1”等。此类数组将无法完全精确地通过格式进行往返。数据是完整的;只有字段名称会有所不同。我们正在努力解决这个问题。此修复程序不需要更改文件格式。具有此类结构的数组仍然可以保存和恢复,并且可以使用 `loadedarray.view(correct_dtype)` 方法恢复正确的 dtype。

文件扩展名#

我们建议使用 `.npy` 和 `.npz` 扩展名来保存此格式的文件。这绝不是强制性的;应用程序可能希望使用这些文件格式,但使用特定于应用程序的扩展名。然而,在没有明显替代方案的情况下,我们建议使用 `.npy` 和 `.npz`。

版本号#

这些格式的版本号独立于 NumPy 的版本号。如果格式升级,`numpy.io` 中的代码仍然能够读取和写入 1.0 版文件。

格式版本 1.0#

前 6 个字节是魔术字符串:正好是 `\x93NUMPY`。

接下来的 1 个字节是一个无符号字节:文件格式的主版本号,例如 `\x01`。

接下来的 1 个字节是一个无符号字节:文件格式的次版本号,例如 `\x00`。注意:文件格式的版本与 numpy 包的版本无关。

接下来的 2 个字节是小端无符号短整型:头部数据 HEADER_LEN 的长度。

接下来的 HEADER_LEN 个字节是描述数组格式的头部数据。它是一个 ASCII 字符串,包含 Python 字面量字典表达式。它以换行符 (`\n`) 结束,并用空格 (`\x20`) 填充,以使 `len(magic string) + 2 + len(length) + HEADER_LEN` 的总长度能被 64 整除,以便对齐。

字典包含三个键:

“descr”dtype.descr

一个对象,可以作为参数传递给 `numpy.dtype` 构造函数以创建数组的 dtype。

“fortran_order”bool

数组数据是 Fortran 顺序还是非 Fortran 顺序。由于 Fortran 顺序数组是非 C 顺序的常见形式,因此我们允许它们直接写入磁盘以提高效率。

“shape”tuple of int

数组的形状。

为了可重复性和可读性,字典键按字母顺序排序。这仅为方便起见。写入器应尽可能实现这一点。读取器不得依赖此。

头部之后是数组数据。如果 dtype 包含 Python 对象(即 `dtype.hasobject` 为 `True`),则数据是数组的 Python pickle。否则,数据是数组的连续(C 顺序或 Fortran 顺序,取决于 `fortran_order`)字节。消费者可以通过将形状给出的元素数量(注意 `shape=()` 表示有 1 个元素)乘以 `dtype.itemsize` 来计算字节数。

格式版本 2.0#

1.0 版本格式只允许数组头部总大小为 65535 字节。结构化数组(具有大量列)可能会超过此限制。2.0 版本格式将头部大小扩展到 4 GiB。`numpy.save` 如果数据需要,将自动以 2.0 格式保存,否则将始终使用更兼容的 1.0 格式。

因此,头部第四个元素的描述已变为:“接下来的 4 个字节是小端无符号整数:头部数据 HEADER_LEN 的长度。”

格式版本 3.0#

此版本用 utf8 编码的字符串替换了 ASCII 字符串(实际上是 latin1),因此支持具有任何 Unicode 字段名的结构化类型。

Notes#

`.npy` 格式,包括创建它的动机和替代方案的比较,在 “npy-format” NEP 中有描述,但细节随着时间而演变,本文档更具时效性。

函数

descr_to_dtype(descr)

根据给定的描述返回一个 dtype。

drop_metadata(dtype, /)

如果 dtype 不包含元数据,则返回不变的 dtype;如果 dtype(或其任何结构化 dtype)包含元数据,则返回 dtype 的副本。

dtype_to_descr(dtype)

从 dtype 获取一个可序列化的描述符。

header_data_from_array_1_0(array)

从 numpy.ndarray 获取头部元数据字典。

isfileobj(f)

magic(major, minor)

返回给定文件格式版本的魔术字符串。

open_memmap(filename[, mode, dtype, shape, ...])

将 .npy 文件打开为内存映射数组。

read_array(fp[, allow_pickle, ...])

从 NPY 文件读取一个数组。

read_array_header_1_0(fp[, max_header_size])

使用 1.0 文件格式版本从类文件对象读取数组头部。

read_array_header_2_0(fp[, max_header_size])

使用 2.0 文件格式版本从类文件对象读取数组头部。

read_magic(fp)

读取魔术字符串以获取文件格式的版本。

write_array(fp, array[, version, ...])

将数组写入 NPY 文件,包括头部。

write_array_header_1_0(fp, d)

使用 1.0 格式为数组写入头部。

write_array_header_2_0(fp, d)

使用 2.0 格式为数组写入头部。