Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/349.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

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/arrays/14.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 将图像堆叠为numpy阵列是否比预分配更快?_Python_Arrays_Image_Numpy - Fatal编程技术网

Python 将图像堆叠为numpy阵列是否比预分配更快?

Python 将图像堆叠为numpy阵列是否比预分配更快?,python,arrays,image,numpy,Python,Arrays,Image,Numpy,我经常需要堆叠2d numpy阵列(tiff图像)。为此,我首先将它们附加到一个列表中,并使用np.dstack。这似乎是获得3D阵列堆叠图像的最快方法。但是,有没有更快/内存效率更高的方法 from time import time import numpy as np # Create 100 images of the same dimention 256x512 (8-bit). # In reality, each image comes from a different file

我经常需要堆叠2d numpy阵列(tiff图像)。为此,我首先将它们附加到一个列表中,并使用np.dstack。这似乎是获得3D阵列堆叠图像的最快方法。但是,有没有更快/内存效率更高的方法

from time import time
import numpy as np

# Create 100 images of the same dimention 256x512 (8-bit). 
# In reality, each image comes from a different file
img = np.random.randint(0,255,(256, 512, 100))

t0 = time()
temp = []
for n in range(100):
    temp.append(img[:,:,n])
stacked = np.dstack(temp)
#stacked = np.array(temp)  # much slower 3.5 s for 100

print time()-t0  # 0.58 s for 100 frames
print stacked.shape

# dstack in each loop is slower
t0 = time()
temp = img[:,:,0]
for n in range(1, 100):
    temp = np.dstack((temp, img[:,:,n]))
print time()-t0  # 3.13 s for 100 frames
print temp.shape

# counter-intuitive but preallocation is slightly slower
stacked = np.empty((256, 512, 100))
t0 = time()
for n in range(100):
    stacked[:,:,n] = img[:,:,n]
print time()-t0  # 0.651 s for 100 frames
print stacked.shape

# (Edit) As in the accepted answer, re-arranging axis to mainly use 
# the first axis to access data improved the speed significantly.
img = np.random.randint(0,255,(100, 256, 512))

stacked = np.empty((100, 256, 512))
t0 = time()
for n in range(100):
    stacked[n,:,:] = img[n,:,:]
print time()-t0  # 0.08 s for 100 frames
print stacked.shape

在与otterb共同努力后,我们得出结论,阵列的预分配是可行的。显然,性能瓶颈是阵列布局,图像编号(n)是变化最快的索引。如果我们将n作为数组的第一个索引(默认为“C”顺序:第一个索引变化最慢,最后一个索引变化最快),我们将获得最佳性能:

from time import time
import numpy as np

# Create 100 images of the same dimention 256x512 (8-bit). 
# In reality, each image comes from a different file
img = np.random.randint(0,255,(100, 256, 512))

# counter-intuitive but preallocation is slightly slower
stacked = np.empty((100, 256, 512))
t0 = time()
for n in range(100):
    stacked[n] = img[n]
print time()-t0  
print stacked.shape

通过保证
temp
中的所有数组都满足此条件,可以避免调用
dstack
。如果满足此条件,只需调用
stacked=np.concatenate(temp,axis=2)
,这可能会节省python开销中的少量时间。如果显示更多代码,可能有更好的方法,但如图所示,最上面的代码几乎是最佳的。temp中的数组都是二维的,我想连接起来得到一个三维数组。因此,np.concatenate(temp,axis=2)将产生一个错误:axis 2超出界限[0,2]。np.concatenate(temp,axis=1)将创建一个2D数组(256x51200)。我遗漏了我的评论的一个关键部分,它应该是这样写的:“…如果满足此条件,
temp
中的所有数组都是3D的…”。应该注意的是,除了非常大的临时大小外,这种节省是微不足道的,可能每个阵列约为2 US。谢谢!我还认为预分配应该是最快的,但不知怎的,它稍微慢了一些。我更新了我的问题,将预分配包括在内。知道为什么吗?嗨,这确实非常有趣,我敢打赌它是fas比如说,当你把时间索引作为第一个索引时,你能试试看它是否有什么不同吗(这个想法是你写的块可以更容易地访问)。猜测一下为什么它可能会慢一些,因为数组的索引有一些开销,例如允许负数。有了cython,你可以去掉这些…你的意思是堆叠的[n,:,:]而不是堆叠[:,:,n]好主意。当我有机会使用我用来评测的那台电脑时,我会试试。是的!我按照你的建议重新排列了轴。现在速度明显快了。我已经接受了你的答案,但是,你可以修改你的答案来澄清第一个轴吗?嗨,奥特布,谢谢你的努力。真的很高兴它能工作。我必须说我也学到了一些从这件事。我把答案的形式,应该是有益于其他人,以及反映你的贡献。你愿意提供你得到的性能,以便我们可以把它也放在那里?