numpy.memmap#

class numpy.memmap(filename, dtype=<class 'numpy.ubyte'>, mode='r+', offset=0, shape=None, order='C')[source]#

创建对存储在磁盘上的 *二进制* 文件中的数组的内存映射。

内存映射文件用于访问磁盘上大文件的小部分片段,而无需将整个文件读入内存。NumPy 的 memmap 是类数组对象。这与 Python 的 mmap 模块不同,后者使用类文件对象。

作为 ndarray 的子类,该类在某些操作中会产生不尽如人意的交互,因为它并不能完美地作为子类存在。使用此子类的替代方案是:自己创建 mmap 对象,然后直接使用 ndarray.__new__ 创建 ndarray,并将创建的对象传递给其 ‘buffer=’ 参数。

该类在未来可能会被转变为一个返回 mmap 缓冲区视图的工厂函数。

将 memmap 实例刷新,以将更改写入文件。目前没有 API 可以关闭底层的 mmap。确保资源确实被关闭是很棘手的,因为它可能在不同的 memmap 实例之间共享。

参数:
filenamestr, 类文件对象, 或 pathlib.Path 实例

用作数组数据缓冲区的路径名或文件对象。

dtype数据类型,可选

用于解释文件内容的的数据类型。默认为 uint8

mode{‘r+’, ‘r’, ‘w+’, ‘c’}, 可选

文件打开的模式

‘r’

打开现有文件以仅供读取。

‘r+’

打开现有文件以进行读取和写入。

‘w+’

创建或覆盖现有文件以进行读取和写入。如果 mode == 'w+',则必须同时指定 shape

‘c’

写时复制(Copy-on-write):赋值会影响内存中的数据,但更改不会保存到磁盘。磁盘上的文件为只读。

默认为 ‘r+’。

offsetint, optional

在文件中,数组数据从该偏移量开始。由于 offset 以字节为单位,它通常应该是 dtype 字节大小的倍数。当 mode != 'r' 时,即使是文件末尾之后的正偏移量也是有效的;文件将被扩展以容纳额外的数据。默认情况下,memmap 将从文件开头开始,即使 filename 是文件指针 fpfp.tell() != 0

shapeint 或 int 序列, 可选

数组所需的形状。如果 mode == 'r'offset 之后剩余的字节数不是 dtype 字节大小的倍数,则必须指定 shape。默认情况下,返回的数组将是 1 维的,元素数量由文件大小和数据类型决定。

版本 2.0 中更改: shape 参数现在可以是任何整数序列类型,以前仅限于元组和整数。

order{‘C’, ‘F’}, optional

指定 ndarray 内存布局的顺序:行优先 (row-major/C-style) 或 列优先 (column-major/Fortran-style)。这仅在形状大于 1 维时有效。默认顺序为 ‘C’。

属性:
filenamestr 或 pathlib.Path 实例

映射文件的路径。

offsetint

文件中的偏移量位置。

modestr

文件模式。

方法

flush()

将数组中的任何更改写入磁盘上的文件。

另请参阅

lib.format.open_memmap

创建或加载一个内存映射的 .npy 文件。

备注

memmap 对象可以在接受 ndarray 的任何地方使用。给定一个 memmap fpisinstance(fp, numpy.ndarray) 返回 True

在 32 位系统上,内存映射文件不能大于 2GB。

当 memmap 导致文件被创建或扩展到超过其文件系统中的当前大小时,新部分的内容是未定义的。在具有 POSIX 文件系统语义的系统上,扩展部分将被填充为零字节。

示例

>>> import numpy as np
>>> data = np.arange(12, dtype=np.float32).reshape((3, 4))

此示例使用临时文件,以便 doctest 不会将文件写入您的目录。您应该使用“正常”的文件名。

>>> from tempfile import mkdtemp
>>> import os.path as path
>>> filename = path.join(mkdtemp(), 'newfile.dat')

创建具有与我们的数据相匹配的 dtype 和 shape 的 memmap

>>> fp = np.memmap(filename, dtype=np.float32, mode='w+', shape=(3,4))
>>> fp
memmap([[0., 0., 0., 0.],
        [0., 0., 0., 0.],
        [0., 0., 0., 0.]], dtype=float32)

将数据写入 memmap 数组

>>> fp[:] = data[:]
>>> fp
memmap([[  0.,   1.,   2.,   3.],
        [  4.,   5.,   6.,   7.],
        [  8.,   9.,  10.,  11.]], dtype=float32)
>>> fp.filename == path.abspath(filename)
True

将内存更改刷新到磁盘,以便重新读取它们

>>> fp.flush()

加载 memmap 并验证数据已存储

>>> newfp = np.memmap(filename, dtype=np.float32, mode='r', shape=(3,4))
>>> newfp
memmap([[  0.,   1.,   2.,   3.],
        [  4.,   5.,   6.,   7.],
        [  8.,   9.,  10.,  11.]], dtype=float32)

只读 memmap

>>> fpr = np.memmap(filename, dtype=np.float32, mode='r', shape=(3,4))
>>> fpr.flags.writeable
False

写时复制 memmap

>>> fpc = np.memmap(filename, dtype=np.float32, mode='c', shape=(3,4))
>>> fpc.flags.writeable
True

可以对写时复制数组进行赋值,但值仅写入数组的内存副本中,而不会写入磁盘

>>> fpc
memmap([[  0.,   1.,   2.,   3.],
        [  4.,   5.,   6.,   7.],
        [  8.,   9.,  10.,  11.]], dtype=float32)
>>> fpc[0,:] = 0
>>> fpc
memmap([[  0.,   0.,   0.,   0.],
        [  4.,   5.,   6.,   7.],
        [  8.,   9.,  10.,  11.]], dtype=float32)

磁盘上的文件未更改

>>> fpr
memmap([[  0.,   1.,   2.,   3.],
        [  4.,   5.,   6.,   7.],
        [  8.,   9.,  10.,  11.]], dtype=float32)

memmap 中的偏移量

>>> fpo = np.memmap(filename, dtype=np.float32, mode='r', offset=16)
>>> fpo
memmap([  4.,   5.,   6.,   7.,   8.,   9.,  10.,  11.], dtype=float32)