将numpy memmap刷新到npy文件

时间:2016-04-21 12:18:04

标签: python numpy mmap memory-mapped-files

是否有方法将numpy memmap数组保存到.npy文件中?显然,有一种方法可以从.npy文件加载这样的数组,如下所示

data = numpy.load("input.npy", mmap_mode='r')

但刷新文件并不等同于以.npy格式存储它。

如果冲洗是唯一的方法,那么有没有办法推断存储阵列的形状?我希望在另一个脚本中自动存储和检索动态形状(可能再次作为memmap)。

我在各个地方搜索过这个,但没有找到任何结果。我存入.npy的方式我现在做的是

numpy.save(output.filename, output.copy())

这违背了使用memmap但保留形状的想法。

注意:我知道hdf5和h5py,但我想知道是否有一个纯粹的numpy解决方案。

2 个答案:

答案 0 :(得分:6)

  

有没有办法推断存储数组的形状?

No。就np.memmap而言,文件只是一个缓冲区 - 它存储数组的内容,但不存储维度,dtype等等。除非它们没有办法推断出这些信息。不知何故包含在数组本身内。如果您已经创建了一个由简单二进制文件支持的np.memmap,那么您需要将其内容写入磁盘上的新.npy文件。

您可以使用numpy.lib.format.open_memmap打开新的.npy文件作为另一个内存映射数组,从而避免在内存中生成副本:

import numpy as np
from numpy.lib.format import open_memmap

# a 10GB memory-mapped array
x = np.memmap('/tmp/x.mm', mode='w+', dtype=np.ubyte, shape=(int(1E10),))

# create a memory-mapped .npy file with the same dimensions and dtype
y = open_memmap('/tmp/y.npy', mode='w+', dtype=x.dtype, shape=x.shape)

# copy the array contents
y[:] = x[:]

答案 1 :(得分:1)

免责声明:以下适用于numpy版本1.11.2(后来我认为),但我尝试的早期版本(1.8.2)发出了错误。

使用np.save保存的数组本质上是一个memmap,其中包含指定dtype,shape和元素顺序的标头。您可以在numpy documentation

中详细了解相关信息

创建np.memmap时,可以使用offset参数为该标头保留空间。注意:文档指定标题长度应为16的倍数:

我们假设您为标题保留5 * 16 = 80个字节(以下更多信息):

import numpy as np
x = np.memmap('/tmp/x.npy', mode='w+', dtype=np.ubyte, shape=(int(1E10),), offset=80)

然后,当您完成对memmap的操作后,使用np.lib.format创建并编写标题:

header = np.lib.format.header_data_from_array_1_0(x)

with open('/tmp/x.npy', 'r+b') as f:
    np.lib.format.write_array_header_1_0(f, header)

请注意,这会从memmap文件的开头写入标题,因此如果len(header) > 80,它将覆盖部分数据,并且您的文件将无法读取。标题是一个固定长度的魔术字符串,两个版本字节,两个指定标题长度的字节,以及一个字典的字符串表示,指定'形状' des'和#39;和' ;为了&#39 ;.如果您知道数组的形状和dtype(descr),则可以轻松计算标题长度(为简单起见,我将其固定在80以上)。

编写标题后,您可以使用np.load加载数据:

y = np.load('/tmp/x.npy')