从文件中读取 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 变量 a
、y
、x
或 z
的成本,因为 zaw lin表示或和计算索引的成本)
当您执行一些 numpy C 代码时,使用 numpy.copy
、numpy.reshape
和 numpy.moveaxis
让 numpy 更新尽可能多的值。
我有一个二进制文件,我正在将它解析为 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 变量 a
、y
、x
或 z
的成本,因为 zaw lin表示或和计算索引的成本)
当您执行一些 numpy C 代码时,使用 numpy.copy
、numpy.reshape
和 numpy.moveaxis
让 numpy 更新尽可能多的值。