了解 Numpy 的 dstack 函数



我很难理解numpy的dstack函数实际在做什么。文件相当稀疏,只是说:

按深度顺序堆叠阵列(沿第三轴(。

获取阵列序列,并将它们沿第三个轴堆叠以形成单个阵列。重建按dsplit划分的数组。这是一种将2D阵列(图像(堆叠成单个阵列的简单方法3D阵列进行处理。

所以,要么我真的很愚蠢,这意味着显而易见,要么我似乎对"堆叠"、"按顺序"、"深度"或"沿轴"这些术语有一些误解。然而,我的印象是,我在vstackhstack的上下文中理解这些术语很好。

举个例子:

In [193]: a
Out[193]: 
array([[0, 3],
       [1, 4],
       [2, 5]])
In [194]: b
Out[194]: 
array([[ 6,  9],
       [ 7, 10],
       [ 8, 11]])
In [195]: dstack([a,b])
Out[195]: 
array([[[ 0,  6],
        [ 3,  9]],
       [[ 1,  7],
        [ 4, 10]],
       [[ 2,  8],
        [ 5, 11]]])

首先,ab没有第三个轴,那么我如何将它们沿着">第三轴"堆叠?其次,假设ab是2D图像的表示,为什么我最终在结果中使用三个2D阵列,而不是"按顺序"使用两个2D阵列?

通过查看输出数组的.shape属性,可以更容易地理解np.vstacknp.hstacknp.dstack*的作用。

使用您的两个示例阵列:

print(a.shape, b.shape)
# (3, 2) (3, 2)
  • np.vstack沿着第一维度连接。。。

    print(np.vstack((a, b)).shape)
    # (6, 2)
    
  • np.hstack沿着第二维度连接。。。

    print(np.hstack((a, b)).shape)
    # (3, 4)
    
  • 并且CCD_ 15沿着第三维度连接。

    print(np.dstack((a, b)).shape)
    # (3, 2, 2)
    

由于ab都是二维的,np.dstack通过插入大小为1的第三个维度来扩展它们。这相当于用np.newaxis(或者None(在三维中对它们进行索引,如下所示:

print(a[:, :, np.newaxis].shape)
# (3, 2, 1)

如果是c = np.dstack((a, b)),则是c[:, :, 0] == ac[:, :, 1] == b

您可以使用np.concatenate更明确地执行相同的操作,如下所示:

print(np.concatenate((a[..., None], b[..., None]), axis=2).shape)
# (3, 2, 2)

*使用import *将模块的全部内容导入全局命名空间被认为是不好的做法,原因有几个。惯用的方法是import numpy as np

x == dstack([a, b])。则x[:, :, 0]a相同,并且x[:, :, 1]b相同。通常,当对2D阵列进行数据封装时,数据封装产生输出,使得output[:, :, n]与第n个输入阵列相同。

如果我们堆叠3D阵列而不是2D阵列:

x = numpy.zeros([2, 2, 3])
y = numpy.ones([2, 2, 4])
z = numpy.dstack([x, y])

z[:, :, :3]将与x相同并且z[:, :, 3:7]将与y相同。

正如您所看到的,我们必须沿着第三个轴进行切片,以恢复dstack的输入。这就是为什么dstack的行为方式。

我想尝试一下直观地解释这一点(尽管公认的答案足够有意义,但我花了几秒钟的时间才在脑海中合理化(。如果我们把2d数组想象成一个列表列表,其中第一个轴给出一个内部列表,第二个轴给出该列表中的值,那么OP数组的视觉表示将是:

a = [
      [0, 3],
      [1, 4],
      [2, 5]
    ]
b = [
      [6,  9],
      [7, 10],
      [8, 11]
    ]
# Shape of each array is [3,2]

现在,根据当前的文档,dstack函数添加了一个第三轴,这意味着每个阵列最终看起来像这样:

a = [
      [[0], [3]],
      [[1], [4]],
      [[2], [5]]
    ]
b = [
      [[6],  [9]],
      [[7], [10]],
      [[8], [11]]
    ]
# Shape of each array is [3,2,1]

现在,在三维中堆叠这两个数组只意味着结果应该像预期的那样:

dstack([a,b]) = [
                  [[0, 6], [3, 9]],
                  [[1, 7], [4, 10]],
                  [[2, 8], [5, 11]]
                ]
# Shape of the combined array is [3,2,2]

希望这能有所帮助。

因为你提到了"images",我认为这个例子会很有用。如果您使用Keras来训练具有输入X的2D卷积网络,那么最好保持X具有维度(#images,dim1ofImage,dim2ofImage(。

image1 = np.array([[4,2],[5,5]])
image2 = np.array([[3,1],[6,7]])
image1 = image1.reshape(1,2,2)
image2 = image2.reshape(1,2,2)
X = np.stack((image1,image2),axis=1) 
X
array([[[[4, 2],
         [5, 5]],
        [[3, 1],
        [6, 7]]]])
np.shape(X)         
X = X.reshape((2,2,2))   
X 
array([[[4, 2],
        [5, 5]],
       [[3, 1],
        [6, 7]]])
X[0] # image 1
array([[4, 2],
       [5, 5]])
X[1] # image 2
array([[3, 1],
       [6, 7]])             

相关内容

  • 没有找到相关文章