内存映像文件是一种将磁盘上的非常大的二进制数据文件当做内存中的数组进行处理的方式。NumPy实现了一个类似于ndarray的memmap对象,它允许将大文件分成小段进行读写,而不是一次性将整个数组读入内存。memmap也拥有跟普通数组一样的方法,因此,基本上只要是能用于ndarray的算法就也能用于memmap。
使用函数np.memmap并传入一个文件路径、数据类型、形状以及文件模式,即可创建一个新的memmap:
为存储在磁盘上的二进制文件中的数组创建内存映射。
内存映射文件用于访问磁盘上的大段文件,而无需将整个文件读入内存。NumPy的memmap是类似数组的对象。这与Python的mmap
模块不同,后者使用类似文件的对象。
这个ndarray的子类与某些操作有一些不愉快的交互,因为它不太适合作为子类。使用此子类的另一种方法是自己创建mmap
对象,然后直接使用ndarray .__ new__创建一个ndarray,传递在其'buffer ='参数中创建的对象。
此类可能在某些时候被转换为工厂函数,该函数将视图返回到mmap缓冲区。
删除memmap实例以关闭memmap文件。
参数: | filename : str,类文件对象或pathlib.Path实例 要用作数组数据缓冲区的文件名或文件对象。 dtype : 数据类型,可选 用于解释文件内容的数据类型。默认是 模式 : {'r +','r','w +','c'},可选 该文件以此模式打开:
默认为'r +'。 offset : int,可选 在该文件中,数组数据从此偏移量开始。由于偏移量是以字节为单位测量的,因此通常应该是字节大小的倍数 形状 : 元组,可选 所需的阵列形状。如果和偏移后的剩余字节数不是字节大小的倍数,则必须指定。默认情况下,返回的数组将是1-D,元素数由文件大小和数据类型确定。 顺序 : {'C','F'},可选 指定ndarray内存布局的顺序: row-major,C-style或column-major,Fortran-style。这仅在形状大于1-D时有效。默认顺序为“C”。 |
---|
也可以看看
lib.format.open_memmap
创建或加载内存映射.npy
文件。
笔记
memmap对象可以在接受ndarray的任何地方使用。给出一个memmap fp
,返回 。isinstance(fp, numpy.ndarray)
True
在32位系统上,内存映射文件不能大于2GB。
当memmap导致文件系统中创建或扩展文件超出其当前大小时,新部件的内容未指定。在具有POSIX文件系统语义的系统上,扩展部分将填充零字节。
例子
>>>
>>> data = np.arange(12, dtype='float32')
>>> data.resize((3,4))
此示例使用临时文件,以便doctest不会将文件写入您的目录。您将使用“正常”文件名。
>>>
>>> from tempfile import mkdtemp
>>> import os.path as path
>>> filename = path.join(mkdtemp(), 'newfile.dat')
创建一个与我们的数据匹配的dtype和形状的memmap:
>>>
>>> fp = np.memmap(filename, dtype='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
在删除对象之前,删除会将内存更改刷新到磁盘:
>>>
>>> del fp
加载memmap并验证数据是否已存储:
>>>
>>> newfp = np.memmap(filename, dtype='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='float32', mode='r', shape=(3,4))
>>> fpr.flags.writeable
False
写时复制memmap:
>>>
>>> fpc = np.memmap(filename, dtype='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='float32', mode='r', offset=16)
>>> fpo
memmap([ 4., 5., 6., 7., 8., 9., 10., 11.], dtype=float32)
属性: | filename : str或pathlib.Path实例 映射文件的路径。 offset : int 文件中的偏移位置。 模式 : str 文件模式。 |
---|
方法
flush () | 将数组中的任何更改写入磁盘上的文件。 |
首先创建memmap文件my_mnist.data,然后将数据X_train写到my_mnist.data
再次用到时,直接调用,删除之后,就不在有X_ZMS这个数据,释放了内存。