2017-01-17 168 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轴时给予更多的权力。

相关问题