从文件中读取 numpy 数组并解析得非常慢

Reading numpy array from file and parsing very slow

我有一个二进制文件,我正在将它解析为 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)]

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

您的代码似乎有误,我相信 x 和 y 应该在 (sizeZ * x) + (sizeZ * sizeX * y) 假设行主要排序中颠倒过来。在任何情况下,检查下面的代码,验证 reshape 是你想要的。它慢的原因是嵌套的 for 循环。

在python中,for循环是一个非常复杂的结构,开销非常大。因此在大多数情况下,您应该避免 for 循环并使用库提供的函数(它们也有 for 循环但在 c/c++ 中完成)。你会发现 "removing the for loop" 是 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))))

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

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