我想将硬盘上的大记录(12G)映射到numpy数组。 (映射而不是加载以节省内存。)
存储在fortran记录中的数据不是连续的,因为它除以记录标记。记录结构为“标记,数据,标记,数据,......,数据,标记”。数据区域和标记的长度是已知的。
标记之间的数据长度不是4个字节的倍数,否则我可以将每个数据区域映射到数组。
可以通过在memmap中设置偏移来跳过第一个标记,是否可以跳过其他标记并将数据映射到数组?
道歉可能含糊不清,并感谢任何解决方案或建议。
5月15日编辑
这些是fortran无格式文件。存储在记录中的数据是(1024 ^ 3)* 3 float32数组(12Gb)。
大于2千兆字节的可变长度记录的记录布局如下所示:
(有关详细信息,请参阅here - > [记录类型] - > [可变长度记录]部分。)
在我的情况下,除了最后一个,每个子记录具有2147483639个字节的长度,并通过8个字节分离(如你在图中看到的上方,前一子记录的结束标记和一个开始以下之一标记,总共8个字节。
我们可以看到第一个子记录以某个浮点数的前3个字节结束,第二个子记录从其余的1个字节开始,如2147483639 mod 4 = 3.
答案 0 :(得分:3)
我发布了另一个答案,因为the example given here 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))
代表int32
byte_size=32/8
,int16
byte_size=16/8
等等......
如果大小不变,您可以将数据加载到2D数组中,如:
shape = (total_length/size,size)
data = np.memmap('tmp', dtype='i', mode='r+', order='F', shape=shape)
您可以根据需要更改memmap
对象。甚至可以使阵列共享相同的元素。在这种情况下,在一个中进行的更改会在另一个中自动更新。
其他参考资料: