【问题标题】:understanding numpy's dstack function理解 numpy 的 dstack 函数
【发布时间】:2014-09-26 19:17:22
【问题描述】:

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

按顺序深度(沿第三轴)堆叠数组。

获取一系列数组并沿第三轴堆叠它们 制作一个数组。重建除以dsplit 的数组。 这是一种将二维数组(图像)堆叠成单个的简单方法 用于处理的 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 数组?

【问题讨论】:

  • 就像带有一维数组的 vstack 沿着垂直于该一维轴的新轴堆叠它们一样,带有二维数组的 dstack 沿着垂直于两个二维轴的新轴堆叠它们。就像把一堆纸叠在一起一样。
  • @abarnert 但是,当我试图将两张纸叠在一起时,为什么我最终会得到三张纸?
  • 您会在结果中看到 3 个二维数组,因为您正在查看第一个轴,而不是第三个轴。

标签: python numpy concatenation multidimensional-array


【解决方案1】:

通过查看输出数组的.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)
    
  • np.dstack 沿第三维连接。

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

由于ab 都是二维的,np.dstack 通过插入大小为 1 的第三维来扩展它们。这相当于在第三维中使用np.newaxis(或@987654341)对它们进行索引@) 像这样:

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 * 将模块的全部内容导入全局命名空间是considered bad practice for several reasons。惯用的方式是import numpy as np

【讨论】:

  • 更清楚的是,第三个数组索引现在给出了我原来的二维索引所在的平面的高度。我仍然以与 2D 数组相同的方式索引,但现在在您的示例中添加级别 0 或 1。所以: dstack([a,b]) ;索引[0][0][0] = 0; index[0][0][1] = 6. 或平面英语“从级别 1 获取索引 0,0”
【解决方案2】:

x == dstack([a, b])。那么x[:, :, 0]a 相同,x[:, :, 1]b 相同。通常,当 dstacking 二维数组时,dstack 会产生一个输出,使得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 的行为方式。

【讨论】:

    【解决方案3】:

    我想尝试从视觉上解释这一点(尽管接受的答案足够有道理,但我花了几秒钟的时间才将其合理化)。 如果我们将二维数组想象成一个列表列表,其中第一个轴给出内部列表之一,第二个轴给出该列表中的值,那么 OP 数组的视觉表示将是这样的:

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

    现在,根据current documentationdstack 函数添加了第三个轴,这意味着每个数组最终看起来像这样:

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

    现在,将这两个数组堆叠在第 3 维中仅仅意味着结果应该像预期的那样看起来像这样:

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

    希望这会有所帮助。

    【讨论】:

      【解决方案4】:

      因为您提到了“图像”,所以我认为这个示例会很有用。如果您使用 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]])             
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2019-11-27
        • 1970-01-01
        • 2015-08-13
        • 2020-04-03
        • 2018-05-02
        • 2021-04-20
        • 2016-07-31
        相关资源
        最近更新 更多