是否可以用python将磁盘上不连续的数据映射到数组?

问题描述 投票:0回答:1

我想将硬盘上的一个大的 Fortran 记录(12G)映射到 numpy 数组。 (映射而不是加载以节省内存。)

Fortran 记录中存储的数据不是连续的,因为它是由记录标记划分的。记录结构为“标记、数据、标记、数据、...、数据、标记”。数据区域和标记的长度是已知的。

标记之间的数据长度不是4字节的倍数,否则我可以将每个数据区域映射到一个数组。

可以通过在memmap中设置offset来跳过第一个标记,是否可以跳过其他标记并将数据映射到数组?

对可能出现的含糊表达表示歉意,并感谢您提供任何解决方案或建议。


5 月 15 日编辑

这些是 Fortran 未格式化的文件。 record中存储的数据是一个(1024^3)*3 float32数组(12Gb)。

大于2GB的变长记录的记录布局如下所示:

data structure

(详情参见这里 -> [记录类型] -> [可变长度记录]部分。)

在我的例子中,除了最后一个,每个子记录的长度都是 2147483639 字节,并且间隔 8 个字节(如上图所示,前一个子记录的结束标记和后一个子记录的开始标记,8 个字节总共)。

我们可以看到第一个子记录以某个浮点数的前 3 个字节结束,第二个子记录以其余 1 个字节开始,即 2147483639 mod 4 =3。

python arrays numpy fortran hdf5
1个回答
6
投票

可以使用

numpy.memmap
:

offset = 0
data1 = np.memmap('tmp', dtype='i', mode='r+', order='F',
                  offset=0, shape=(size1))
offset += size1*byte_size
data2 = np.memmap('tmp', dtype='i', mode='r+', order='F',
                  offset=offset, shape=(size2))
offset += size1*byte_size
data3 = np.memmap('tmp', dtype='i', mode='r+', order='F',
                  offset=offset, shape=(size3))

您需要根据数据类型设置

byte_size
。例如:

  • int32
    需要
    byte_size=32/8
  • int16
    byte_size=16/8
  • 等等...

如果整个数组的数据类型是恒定的,您可以将数据加载到二维数组中,如下所示:

shape = (total_length/size,size)
data = np.memmap('tmp', dtype='i', mode='r+', order='F', shape=shape)

您可以根据需要更改

memmap
对象。甚至可以使数组共享相同的元素,在这种情况下,所有相应的数组都会感知共享元素中所做的更改。

其他参考:

© www.soinside.com 2019 - 2024. All rights reserved.