了解numpy的dstack功能

tim*_*geb 28 python numpy concatenation multidimensional-array

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

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

采用一系列数组并沿第三轴堆叠它们以形成单个数组.重建数组除以dsplit.这是将2D阵列(图像)堆叠到单个3D阵列中进行处理的简单方法.

所以要么我真的很愚蠢,这个含义是显而易见的,或者我似乎对"堆叠","按顺序","深度明智"或"沿轴"这两个术语有一些误解.但是,我的印象是我在上下文中理解这些术语,vstack并且hstack很好.

我们来看这个例子:

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]]])
Run Code Online (Sandbox Code Playgroud)

首先,ab没有第三轴,所以我将如何堆叠起来一起" 第三轴"以开始?第二,假设a并且b是2D图像的表示,为什么我在结果中最终得到三个 2D数组而不是两个"顺序"的2D数组?

ali*_*i_m 53

通过查看输出数组的属性,更容易理解什么np.vstack,np.hstack以及np.dstack*做什么.shape.

使用两个示例数组:

print(a.shape, b.shape)
# (3, 2) (3, 2)
Run Code Online (Sandbox Code Playgroud)

因为a并且b都是二维的,np.dstack所以通过插入大小为1的第三维来扩展它们.这相当于在第三维中使用np.newaxis(或者替代None)索引它们,如下所示:

print(a[:, :, np.newaxis].shape)
# (3, 2, 1)
Run Code Online (Sandbox Code Playgroud)

如果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)
Run Code Online (Sandbox Code Playgroud)

*由于多种原因,将模块的全部内容导入到全局命名空间中import *认为是不好的做法.惯用的方法是import numpy as np.

  • 谢谢,通过`shape`的解释正是我所需要的. (2认同)

use*_*ica 6

我们x == dstack([a, b]).然后x[:, :, 0]是相同的a,并且x[:, :, 1]是相同的b.通常,当dstacking 2D数组时,dstack产生的输出output[:, :, n]与第n个输入数组相同.

如果我们堆叠3D数组而不是2D:

x = numpy.zeros([2, 2, 3])
y = numpy.ones([2, 2, 4])
z = numpy.dstack([x, y])
Run Code Online (Sandbox Code Playgroud)

然后z[:, :, :3]将是相同的x,并且z[:, :, 3:7]将是相同的y.

如您所见,我们必须沿第三轴采取切片来恢复输入dstack.这就是它的dstack行为方式.


goe*_*ash 5

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

a = [
      [0, 3],
      [1, 4],
      [2, 5]
    ]
b = [
      [6,  9],
      [7, 10],
      [8, 11]
    ]
# Shape of each array is [3,2]
Run Code Online (Sandbox Code Playgroud)

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

a = [
      [[0], [3]],
      [[1], [4]],
      [[2], [5]]
    ]
b = [
      [[6],  [9]],
      [[7], [10]],
      [[8], [11]]
    ]
# Shape of each array is [3,2,1]
Run Code Online (Sandbox Code Playgroud)

现在,将这两个数组堆叠在第三维中仅仅意味着结果应该像预期的那样如下所示:

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

希望这可以帮助。