【问题标题】:Reading numpy array from file and parsing very slow从文件中读取numpy数组并解析非常慢
【发布时间】:2018-05-04 17:20:13
【问题描述】:

我有一个二进制文件,我正在将其解析为 Python 中的一个 numpy 数组,如下所示:

bytestream= np.fromfile(path, dtype=np.int16)

 for a in range(sizeA):
        for x in range(0, sizeX):
            for y in range(0, sizeY):
                for z in range(0, sizeZ):
                    parsed[a, x, y, z] = bytestream[z + (sizeZ * x) + (sizeZ * sizeX * y) + (sizeZ * sizeX * sizeY * a)]

但是,这非常非常慢。谁能告诉我为什么以及如何加快速度?

【问题讨论】:

    标签: python numpy numpy-memmap fromfile


    【解决方案1】:

    您正在逐个单元格地更新 numpy 数组 parsed,必须在 python 和每个单元格的 numpy 的 C 实现之间反弹。这是一个严重的开销。 (更不用说在每次 python 迭代时更新 python 变量 ayxz 的成本,以及计算索引的成本)

    当您执行一些 numpy C 代码时,使用 numpy.copynumpy.reshapenumpy.moveaxis 在一批中更新尽可能多的值。

    【讨论】:

    • 感谢您提供更多有用的评论!
    【解决方案2】:

    您的代码似乎犯了一个错误,我认为 x 和 y 应该在 (sizeZ * x) + (sizeZ * sizeX * y) 中颠倒,假设行主要排序。无论如何,请检查下面的代码,它可以验证 reshape 是您想要的。它慢的原因是嵌套的 for 循环。

    在 python 中,for 循环是一个非常复杂的结构,开销非常大。因此,在大多数情况下,您应该避免使用 for 循环并使用库提供的函数(也有 for 循环,但在 c/c++ 中完成)。您会发现“删除 for 循环”是 numpy 中的一个常见问题,因为大多数人会首先以最直接的方式尝试一些他们知道的算法(例如卷积,最大池化)。并意识到它非常慢,并寻找基于 numpy api 的巧妙替代方案,其中大部分计算转移到 c++ 端,而不是在 python 中发生。

    import numpy as np
    
    # gen some data 
    arr= (np.random.random((4,4,4,4))*10).astype(np.int16)
    arr.tofile('test.bin')
    
    # original code
    bytestream=np.fromfile('test.bin',dtype=np.int16)
    parsed=np.zeros(arr.shape,dtype=np.int16)
    sizeA,sizeX,sizeY,sizeZ=arr.shape
    for a in range(sizeA):
        for x in range(0, sizeX):
            for y in range(0, sizeY):
                for z in range(0, sizeZ):
                    parsed[a, x, y, z] = bytestream[z + (sizeZ * y) + (sizeZ * sizeX * x) + (sizeZ * sizeX * sizeY * a)]
    
    print(np.allclose(arr,parsed))
    print(np.allclose(arr,bytestream.reshape((sizeA,sizeX,sizeY,sizeZ))))
    

    【讨论】:

    • 这并没有回答我的问题,为什么代码很慢,我认为我应该使用 reshape,因为它使我的代码更快。
    猜你喜欢
    • 2021-10-12
    • 2019-04-30
    • 2015-08-19
    • 1970-01-01
    • 2011-08-11
    • 1970-01-01
    • 2016-08-12
    • 1970-01-01
    • 2015-08-26
    相关资源
    最近更新 更多