2017-01-17 167 views
2

我有大約150,000個圖像,我想要加載一個形狀爲[index][y][x][channel]的numpy數組。目前,我這樣做:如何在4D numpy數組中快速放置很多2D numpy數組?

images = numpy.zeros((len(data), 32, 32, 1)) 
for i, fname in enumerate(data): 
    img = scipy.ndimage.imread(fname, flatten=False, mode='L') 
    img = img.reshape((1, img.shape[0], img.shape[1], 1)) 
    for y in range(32): 
     for x in range(32): 
      images[i][y][x][0] = img[0][y][x][0] 

這樣的作品,但我認爲必須有一個比遍歷元素更好的解決方案。我可以擺脫重塑,但這仍然會留下兩個嵌套的for-loops。

什麼是達到相同的最快方式images 4D陣列,有150,000圖像需要加載到它?

回答

1

通常,您在處理numpy數組時不需要複製單個元素。你可以只指定軸(如果他們是平等的大小或broadcastable)你想你的陣列複製到和/或來自:

images[i,:,:,0] = img[0,:,:,0] 

,而不是你的循環。事實上,你並不需要重塑可言:

images[i,:,:,0] = scipy.ndimage.imread(fname, flatten=False, mode='L') 

這些:指定您希望這些軸線被保留(不切)和numpy的支持數組數組賦值,例如:

>>> a = np.zeros((3,3,3)) 
>>> a[0, :, :] = np.ones((3, 3)) 
>>> a 
array([[[ 1., 1., 1.], 
     [ 1., 1., 1.], 
     [ 1., 1., 1.]], 

     [[ 0., 0., 0.], 
     [ 0., 0., 0.], 
     [ 0., 0., 0.]], 

     [[ 0., 0., 0.], 
     [ 0., 0., 0.], 
     [ 0., 0., 0.]]]) 

>>> a = np.zeros((3,3,3)) 
>>> a[:, 1, :] = np.ones((3, 3)) 
>>> a 
array([[[ 0., 0., 0.], 
     [ 1., 1., 1.], 
     [ 0., 0., 0.]], 

     [[ 0., 0., 0.], 
     [ 1., 1., 1.], 
     [ 0., 0., 0.]], 

     [[ 0., 0., 0.], 
     [ 1., 1., 1.], 
     [ 0., 0., 0.]]]) 
+0

由於'(x,y,1)'不會廣播到'(x,y)',所以不能確定這將適用於'flatten = False'。不是'images [i] = scipy.ndimage.imread(fname,flatten = False,mode ='L')'夠了嗎? – Eric

+0

@Eric好問題,我認爲['mode ='L''](http://pillow.readthedocs.io/en/3.4.x/handbook/concepts.html#modes)只是定義了「位」灰度(8位),但會返回一個二維數組。 – MSeifert

0

本質上有2個接近

res = np.zeros((<correct shape>), dtype) 
for i in range(...): 
    img = <load> 
    <reshape if needed> 
    res[i,...] = img 

如果您已經正確選擇了res的初始形狀,您應該可以將每個圖像陣列複製到其插槽中,而無需循環或進行大量重塑。

其它方式使用列表追加

alist = [] 
for _ in range(...): 
    img = <load> 
    <reshape> 
    alist.append(img) 
res = np.array(alist) 

此收集所有組件陣列到一個列表,並使用np.array到它們連接成一個陣列在開始一個新的層面。 np.stack在選擇concatenation軸時給予更多的權力。

相關問題