如何在4D numpy阵列中快速放置许多2D numpy数组?

时间:2017-01-17 23:57:15

标签: python arrays numpy multidimensional-array

我有大约150,000张图像,我想以一个形状为[index][y][x][channel]的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循环。

获得相同images 4D阵列的最快方法是什么,需要加载150,000张图像?

2 个答案:

答案 0 :(得分:1)

通常,在处理numpy-arrays时不需要复制单个元素。您只需指定要将阵列复制到和/或从中复制的轴(如果它们大小相同或可广播):

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.]]])

答案 1 :(得分:0)

基本上有两种方法

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

如果您已正确选择res的初始形状,则应该能够将每个图像阵列复制到其插槽中,而无需循环或重新整形。

另一种方法使用list append

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

这会将所有组件数组收集到一个列表中,并使用np.array将它们连接到一个数组中,并在开始时使用新维度。 np.stack在选择concatenation轴方面提供了更多的力量。