高效读取二进制文件中的值

时间:2011-11-02 13:54:24

标签: python

我有很多包含数字模型输出的二进制文件。它们是包含输出为浮点数的平面二进制文件。这些文件对应于以t-z-y-x顺序排序的四维数组,其中x变化最快。问题是,对于给定的x,y和z,我需要所有t的值。简单的解决方案是简单地将所有内容读入一个大的numpy数组并采用data[:,z,y,x]当然但效率不高(我需要读取很多文件)。

我现在提出的是以下内容(假设start_indexvolume_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更不容易。也没有改变文件格式。

2 个答案:

答案 0 :(得分:1)

可能的选项可能涉及

  1. 使用mmap

    通过这个,您可以将文件映射到内存区域,使其内容可以像在RAM中一样访问。一旦访问/需要组件就会被读入,可能是OS的正常页面大小(4 kiB)。

  2. 将完整的文件读入内存。这与mmap基本相同,但没有OS的帮助。 OTOH,它可以在一次运行中完成,而不是以4 kiB步骤完成。

  3. 如果您有数据在RAM中(在文件中),则可以使用StringIO再次模拟文件并将array.fromfile()与其一起提供。

    第二眼看到它,你可以省略StringIO内容并改用array.fromstring()

    通常只使用一次读取(或几次读取)比重复infile.seek()data.fromfile(infile,1)次调用更快,特别是如果每​​次调用只读取一个值。 (除非您的步长(volume_size)足够大 - 跳过大约几百到几千字节 - 然后它可以更快地按照您的方式执行...)

答案 1 :(得分:1)

如果我是你,我会看看numpy.memmap。我过去用它来解决与你类似的问题,效果很好。