用NumPy进行深度堆叠

时间:2018-05-05 22:21:31

标签: python arrays numpy

我正在使用以下代码并获得大小为(2,9)的输出numpy ndarray,然后我尝试重塑为大小(3,3,2)。我希望调用reshape使用(3,3,2)作为新数组的维度将采用2x9数组的每个并将其整形为3x3数组并将这两个3x3数组包装成另一个阵列。

例如,当我索引结果时,我想要以下行为:

input: print(result)
output: [[ 2.  2.  1.  0.  8.  5.  2.  4.  5.]
         [ 4.  7.  5.  6.  4.  3. -3.  2.  1.]]

result = result.reshape((3,3,2))

DESIRED NEW BEHAVIOR
input: print(result[:,:,0])
output: [[2. 2. 1.]
         [0. 8. 5.]
         [2. 4. 5.]]

input: print(result[:,:,1])
output: [[ 4.  7.  5.]
         [ 6.  4.  3.]
         [-3.  2.  1.]]

ACTUAL NEW BEHAVIOR
input: print(result[:,:,0])
output: [[2. 1. 8.]
         [2. 5. 7.]
         [6. 3. 2.]]

input: print(result[:,:,1])
output: [[ 2.  0.  5.]
         [ 4.  4.  5.]
         [ 4. -3.  1.]]

有没有办法指定重塑我想沿着深度维逐行?我很困惑为什么默认情况下numpy会为重塑它做出选择。

以下是我用于生成结果矩阵的代码,此代码可能是也可能不是分析我的问题所必需的。我觉得好像没有必要,但包括它是为了完整性:

import numpy as np

# im2col implementation assuming width/height dimensions of filter and input_vol
# are the same (i.e. input_vol_width is equal to input_vol_height and the same
# for the filter spatial dimensions, although input_vol_width need not equal
# filter_vol_width)

def im2col(input, filters, input_vol_dims, filter_size_dims, stride):
    receptive_field_size = 1
    for dim in filter_size_dims:
        receptive_field_size *= dim

    output_width = output_height = int((input_vol_dims[0]-filter_size_dims[0])/stride + 1)

    X_col = np.zeros((receptive_field_size,output_width*output_height))

    W_row = np.zeros((len(filters),receptive_field_size))

    pos = 0
    for i in range(0,input_vol_dims[0]-1,stride):
        for j in range(0,input_vol_dims[1]-1,stride):
           X_col[:,pos] = input[i:i+stride+1,j:j+stride+1,:].ravel()
           pos += 1

    for i in range(len(filters)):
        W_row[i,:] = filters[i].ravel()

    bias = np.array([[1], [0]])

    result = np.dot(W_row, X_col) + bias

    print(result)


if __name__ == '__main__':
    x = np.zeros((7, 7, 3))

    x[:,:,0] = np.array([[0,0,0,0,0,0,0],
                         [0,1,1,0,0,1,0],
                         [0,2,2,1,1,1,0],
                         [0,2,0,2,1,0,0],
                         [0,2,0,0,1,0,0],
                         [0,0,0,1,1,0,0],
                         [0,0,0,0,0,0,0]])

    x[:,:,1] = np.array([[0,0,0,0,0,0,0],
                         [0,2,0,1,0,2,0],
                         [0,0,1,2,1,0,0],
                         [0,2,0,0,2,0,0],
                         [0,2,1,0,0,0,0],
                         [0,1,2,2,2,0,0],
                         [0,0,0,0,0,0,0]])

    x[:,:,2] = np.array([[0,0,0,0,0,0,0],
                         [0,0,0,2,1,1,0],
                         [0,0,0,2,2,0,0],
                         [0,2,1,0,2,2,0],
                         [0,0,1,2,1,2,0],
                         [0,2,0,0,2,1,0],
                         [0,0,0,0,0,0,0]])

    w0 = np.zeros((3,3,3))

    w0[:,:,0] = np.array([[1,1,0],
                          [1,-1,1],
                          [-1,1,1]])

    w0[:,:,1] = np.array([[-1,-1,0],
                          [1,-1,1],
                          [1,-1,-1]])

    w0[:,:,2] = np.array([[0,0,0],
                          [0,0,1],
                          [1,0,1]]


    w1 = np.zeros((3,3,3))

    w1[:,:,0] = np.array([[0,-1,1],
                         [1,1,0],
                         [1,1,0]])

    w1[:,:,1] = np.array([[-1,-1,1],
                          [1,0,1],
                          [0,1,1]])

    w1[:,:,2] = np.array([[-1,-1,0],
                          [1,-1,0],
                          [1,1,0]])


    filters = np.array([w0,w1])

    im2col(x,np.array([w0,w1]),x.shape,w0.shape,2)

2 个答案:

答案 0 :(得分:3)

让我们稍微改变一下,然后做一个深度dstack

arr = np.dstack(result.reshape((-1,3,3)))

arr[..., 0]
array([[2., 2., 1.],
       [0., 8., 5.],
       [2., 4., 5.]])

答案 1 :(得分:2)

重塑保持元素的原始顺序

In [215]: x=np.array(x)
In [216]: x.shape
Out[216]: (2, 9)

将9号尺寸重塑为3x3可保持您想要的元素顺序:

In [217]: x.reshape(2,3,3)
Out[217]: 
array([[[ 2.,  2.,  1.],
        [ 0.,  8.,  5.],
        [ 2.,  4.,  5.]],

       [[ 4.,  7.,  5.],
        [ 6.,  4.,  3.],
        [-3.,  2.,  1.]]])

但是你必须用[0,:,:]对其进行索引才能看到其中一个块。

要使用[:,:,0]查看相同的块,您必须将该尺寸2维移动到末尾。 COLDSPEED's dstack通过迭代第一维,并在新的第三维上连接2个块(每个3x3)来做到这一点。另一种方法是使用transpose重新排序维度:

In [218]: x.reshape(2,3,3).transpose(1,2,0)
Out[218]: 
array([[[ 2.,  4.],
        [ 2.,  7.],
        [ 1.,  5.]],

       [[ 0.,  6.],
        [ 8.,  4.],
        [ 5.,  3.]],

       [[ 2., -3.],
        [ 4.,  2.],
        [ 5.,  1.]]])
In [219]: y = _
In [220]: y.shape
Out[220]: (3, 3, 2)
In [221]: y[:,:,0]
Out[221]: 
array([[2., 2., 1.],
       [0., 8., 5.],
       [2., 4., 5.]])