Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/ruby/23.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 有效读取二进制文件中的值_Python - Fatal编程技术网

Python 有效读取二进制文件中的值

Python 有效读取二进制文件中的值,python,Python,我有很多包含数值模型输出的二进制文件。它们是以浮点数形式包含输出的平面二进制文件。这些文件对应于按t-z-y-x顺序排序的四维数组,x变化最快。问题是,对于给定的x,y和z,我需要所有t的值。简单的解决方案是将所有内容读入一个大的numpy数组并获取数据[:,z,y,x]当然可以,但效率不是很高(我需要读取许多文件) 我现在想到的是以下内容(假设start\u index和volume\u size表示正确的内容): 我不必担心终端性和可移植性(尽管后者当然有一些优点)。整个程序都是在Linux

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

我现在想到的是以下内容(假设
start\u index
volume\u size
表示正确的内容):


我不必担心终端性和可移植性(尽管后者当然有一些优点)。整个程序都是在Linux上运行的,它不太可能在其他系统上运行。所以问题是:有没有一种更高性能的方法可以做到这一点?这是在许多文件上完成的。我尝试了并行化,但没有真正的帮助。获取新硬件不是一种选择,SSD由于涉及的数据量更是如此。两者都没有改变文件格式。

可能的选项包括

  • 使用

    这样,您可以将文件映射到内存区域,使其内容可以像在RAM中一样访问。组件一经访问/需要就被读取,可能是操作系统的正常页面大小(4kib)

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

  • 如果RAM中有数据(在文件中),则可以使用再次模拟文件,并将其提供给
    数组.fromfile()

    再次浏览之后,您可以省略
    StringIO
    内容,改用
    array.fromstring()


    仅使用一次读取(或少量读取)通常应比重复的
    infle.seek()
    data.fromfile(infle,1)
    调用更快,尤其是在每次调用仅读取一个值的情况下。(除非你的步长(
    volume\u size
    )足够大——跳过几百到几千个字节——那么按你的方式做可能会更快……

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

    我还没有掌握mmap的窍门,也不知道StringIO的用途。也许你可以详细说明一下?根据我的经验,读取整个文件的速度较慢。这些文件不是很大(大约10MB),但我可能需要处理数千个文件。为了更精确,编辑了我的答案。谢谢。我会调查的。关键是,我使用infle.seek()跳过了大约半兆字节,所以是的,我的步长非常大。因此您有大约20个
    read()
    调用,每个调用读取几个字节。在这种情况下,忘了我写的东西吧——你的方法应该更快。试过之后,我的方法稍微有点优势并不重要。这让我产生了这样的假设:我或多或少是在尽我所能做到最好。谢谢你的解释,这很有趣。谢谢。这似乎不是更快,而是生成更好的代码。
    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)