是否可以使用 python 将磁盘上的不连续数据映射到数组?
Posted
技术标签:
【中文标题】是否可以使用 python 将磁盘上的不连续数据映射到数组?【英文标题】:Is it possible to map a discontiuous data on disk to an array with python? 【发布时间】:2013-05-07 02:21:19 【问题描述】:我想将硬盘上的一个大的 fortran 记录 (12G) 映射到一个 numpy 数组。 (映射而不是加载以节省内存。)
存储在 fortran 记录中的数据不连续,因为它被记录标记分割。记录结构为“标记,数据,标记,数据,...,数据,标记”。数据区域和标记的长度是已知的。
标记之间的数据长度不是4字节的倍数,否则我可以将每个数据区域映射到一个数组中。
第一个标记可以通过在memmap中设置偏移量来跳过,是否可以跳过其他标记并将数据映射到数组?
对可能的模棱两可表达道歉,并感谢任何解决方案或建议。
5 月 15 日编辑
这些是 fortran 未格式化的文件。 record 中存储的数据是一个 (1024^3)*3 float32 数组 (12Gb)。
大于2G的变长记录的记录布局如下所示:
(详情见here -> [记录类型] -> [可变长度记录]。)
在我的例子中,除了最后一个,每个子记录的长度为 2147483639 字节,并由 8 个字节分隔(如上图所示,前一个子记录的结束标记和下一个子记录的开始标记,共 8 个字节)。
我们可以看到第一个子记录以某个浮点数的前 3 个字节结束,第二个子记录以 2147483639 mod 4 =3 的其余 1 个字节开始。
【问题讨论】:
你能告诉我们更多关于数据结构的细节吗?根据我认为您所说的,您的标记之间有可变长度数组?它们是如何打包的(例如 float、int8、int16 等)? 感谢您的关注,对于缺乏细节深表歉意。添加了更多信息。我正在按照 Castro 的建议尝试 h5py。 抱歉,我没有通知你@JoeKington。 【参考方案1】:我发布了另一个答案,因为 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
等等...
如果大小不变,您可以将数据加载到二维数组中,例如:
shape = (total_length/size,size)
data = np.memmap('tmp', dtype='i', mode='r+', order='F', shape=shape)
您可以随意更改memmap
对象。甚至可以使数组共享相同的元素。在这种情况下,对其中一个所做的更改会在另一个中自动更新。
其他参考资料:
Working with big data in python and numpy, not enough ram, how to save partial results on disc?
numpy.memmap
documentation here.
【讨论】:
我可以使用 memmap 访问 12GB 文件而没有任何错误。然而,仍然存在两个问题。第一个是字节序。 order='F' 用于二维(或更高)数组存储顺序而不是字节序,所以我必须做额外的字节序切换。第二次标记与数据混合,我不知道如何挑选标记。也许我对这个问题的描述不清楚。 或者我可以使用形状和偏移量来读取文件的第一个子记录,问题仍然存在——如何将多个子记录放在一起?我很抱歉英语表达不好。 Endian 问题解决了,只要设置 dtype 为 '>' 即 test = np.memmap(file_path, dtype='>i', mode='r', order='F')跨度> @substructure 如果您认为此解决方案已经令人满意,您可以将其切换为已接受 非常感谢您的帮助。恐怕主要问题仍然存在 - 是否可以将数据(排除标记)映射到数组。现在我可以将整个文件映射到一个数组,但数据和标记仍然是交错的。对纯数据做索引不太方便。以上是关于是否可以使用 python 将磁盘上的不连续数据映射到数组?的主要内容,如果未能解决你的问题,请参考以下文章
如何禁用 docker Thinpooldev 上的写屏障?
是否可以使用 pymssql 将 python 列表写入数据库?