Мне часто приходится складывать 2d массивы numpy (tiff images). Для этого я сначала добавлю их в список и использую np.dstack. Это, по-видимому, самый быстрый способ получить 3D-массивы, складывающие изображения. Но есть ли более быстрый/эффективный с точки зрения памяти способ?стек изображений как numpy массив быстрее (чем preallocation)?
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
Вы можете избежать вызова 'dstack' гарантируя, что все массивы в 'temp', если это условие выполнено, вы можете просто вызвать' stacked = np.concatenate (temp, axis = 2) ', что может сэкономить небольшое количество времени в служебных данных python. Если вы показываете больше кода, может быть лучший способ сделать это, но, как показано, верхний код практически оптимален. – Daniel
Массивы в temp все 2D, и я хочу объединиться, чтобы получить 3D-массив. Таким образом, np.concatenate (temp, axis = 2) вызовет ошибку: ось 2 выходит за пределы [0, 2). np.concatenate (temp, axis = 1) создаст 2D-массив (256x51200). – otterb
Я пропустил критическую часть моего комментария, он должен был прочитать «... все массивы в« temp »являются 3D, если это условие выполнено». Следует отметить, что эта экономия тривиальна, за исключением очень больших размеров temp, вероятно, порядка ~ 2us на массив. – Daniel