我有很多包含数字模型输出的二进制文件。它们是包含输出为浮点数的平面二进制文件。这些文件对应于以t-z-y-x顺序排序的四维数组,其中x变化最快。问题是,对于给定的x,y和z,我需要所有t的值。简单的解决方案是简单地将所有内容读入一个大的numpy数组并采用data[:,z,y,x]
当然但效率不高(我需要读取很多文件)。
我现在提出的是以下内容(假设start_index
和volume_size
代表正确的事情):
data=array.array('f')
with file(my_filename,'rb') as infile:
for hour in range(amount_of_steps):
if hour==0:
infile.seek(start_index*data.itemsize,0)
else:
infile.seek(data.itemsize*volume_size,1)
data.fromfile(infile,1)
我不必担心端点和便携性(虽然后者当然有一些优点)。整个事情在Linux上运行,它不太可能在其他东西上运行。所以问题是:有没有办法以更高的性能做到这一点?这是在许多文件上完成的。我尝试了并行化,但它并没有真正帮助。获取新硬件不是一种选择,而且由于涉及的数据量较多,SSD更不容易。也没有改变文件格式。
答案 0 :(得分:1)
可能的选项可能涉及
使用mmap
。
通过这个,您可以将文件映射到内存区域,使其内容可以像在RAM中一样访问。一旦访问/需要组件就会被读入,可能是OS的正常页面大小(4 kiB)。
将完整的文件读入内存。这与mmap基本相同,但没有OS的帮助。 OTOH,它可以在一次运行中完成,而不是以4 kiB步骤完成。
如果您有数据在RAM中(在文件中),则可以使用StringIO
再次模拟文件并将array.fromfile()
与其一起提供。
第二眼看到它,你可以省略StringIO
内容并改用array.fromstring()
。
通常只使用一次读取(或几次读取)比重复infile.seek()
和data.fromfile(infile,1)
次调用更快,特别是如果每次调用只读取一个值。 (除非您的步长(volume_size
)足够大 - 跳过大约几百到几千字节 - 然后它可以更快地按照您的方式执行...)
答案 1 :(得分:1)
如果我是你,我会看看numpy.memmap
。我过去用它来解决与你类似的问题,效果很好。