将 2D 数组堆叠成 3D 数组

Stacking 2D arrays into a 3D array

我有一个非常简单的问题,但我就是想不通。我想将一堆 2D numpy 数组沿着第三维(深度)一个一个地堆叠成一个 3D 数组。

我知道我可以像这样使用 np.stack()

d1 = np.arange(9).reshape(3,3)
d2 = np.arange(9,18).reshape(3,3)

foo = np.stack((d1,d2))

然后我得到

print(foo.shape)
>>> (2, 3, 3)
print(foo)
>>> [[[ 0  1  2]
      [ 3  4  5]
      [ 6  7  8]]

     [[ 9 10 11]
      [12 13 14]
      [15 16 17]]]

到目前为止,这几乎就是我想要的。不过,我在这里有点困惑,深度维度在这里被索引为第一个维度。 但是,我现在想沿着 第一维添加新的 3x3 数组(?)(这让我很困惑),就像这样。

d3 = np.arange(18,27).reshape(3,3)
foo = np.stack((foo,d3))

这不起作用。我知道现在数组的维度有问题,但这里没有 vstack, hstack, dstack 工作。我现在想要的就是这个。

print(foo)
>>> [[[ 0  1  2]
      [ 3  4  5]
      [ 6  7  8]]

     [[ 9 10 11]
      [12 13 14]
      [15 16 17]]

     [[18 19 20]
      [21 22 23]
      [24 25 26]]]

然后就可以像这样添加更多数组了。

当然,我看了一些关于这个主题的问题,但我仍然无法理解 3D 数组(尤其是 np.dstack())并且不知道如何解决我的问题。

为什么不直接在单个堆栈中添加 d1、d2、d3 (np.stack((d1, d2, d3)))?重复连接数组通常是不好的做法。

无论如何,您可以使用:

np.stack((*foo, d3))

或:

np.vstack((foo, d3[None]))

输出:

array([[[ 0,  1,  2],
        [ 3,  4,  5],
        [ 6,  7,  8]],

       [[ 9, 10, 11],
        [12, 13, 14],
        [15, 16, 17]],

       [[18, 19, 20],
        [21, 22, 23],
        [24, 25, 26]]])

您正在寻找np.vstack

np.vstack((d1,d2,d3)).reshape(3,3,3)

或迭代

foo = np.vstack((d1, d2))
foo = np.vstack((foo, d3))

制作 2 个形状各异的数组(这样就清楚了 2,3 和 4 的来源):

In [123]: d1 = np.arange(12).reshape(3,4)
     ...: d2 = np.arange(12,24).reshape(3,4)

将它们组合成一个新数组 - 结果是 (2,3,4)。请注意 [] 是如何嵌套的,就好像您有一个包含 2 个列表的列表,每个列表都有 3 个长度为 4 的列表。

In [124]: np.array((d1,d2))
Out[124]: 
array([[[ 0,  1,  2,  3],
        [ 4,  5,  6,  7],
        [ 8,  9, 10, 11]],

       [[12, 13, 14, 15],
        [16, 17, 18, 19],
        [20, 21, 22, 23]]])
使用默认轴的

stack 做同样的事情 - 沿着新的主维度连接 (3,4) 数组:

In [125]: np.stack((d1,d2))
Out[125]: 
array([[[ 0,  1,  2,  3],
        [ 4,  5,  6,  7],
        [ 8,  9, 10, 11]],

       [[12, 13, 14, 15],
        [16, 17, 18, 19],
        [20, 21, 22, 23]]])

创建一个 (3,2,4) 数组:

In [126]: np.stack((d1,d2), axis=1)
Out[126]: 
array([[[ 0,  1,  2,  3],
        [12, 13, 14, 15]],

       [[ 4,  5,  6,  7],
        [16, 17, 18, 19]],

       [[ 8,  9, 10, 11],
        [20, 21, 22, 23]]])

和一个 (3,4,2):

In [127]: np.stack((d1,d2), axis=2)
Out[127]: 
array([[[ 0, 12],
        [ 1, 13],
        [ 2, 14],
        [ 3, 15]],

       [[ 4, 16],
        [ 5, 17],
        [ 6, 18],
        [ 7, 19]],

       [[ 8, 20],
        [ 9, 21],
        [10, 22],
        [11, 23]]])

通常 depth 是最后一个维度。 np.dstack.

中的 d 暗示了这一点

vstack 在现有的第一个维度上加入它们,形成一个 (2*3, 4) 数组:

In [128]: np.vstack((d1,d2))
Out[128]: 
array([[ 0,  1,  2,  3],
       [ 4,  5,  6,  7],
       [ 8,  9, 10, 11],
       [12, 13, 14, 15],
       [16, 17, 18, 19],
       [20, 21, 22, 23]])

所有这些 *stack 函数调整尺寸然后使用 np.concatenate。默认 stack 添加一个新的前导尺寸,如:

In [129]: np.concatenate((d1[None,:,:], d2[None,:,:])).shape
Out[129]: (2, 3, 4)

虽然 vstack 可以在循环中重复使用,但前提是您从适当的数组开始,它很慢。最好收集整个数组列表,只做一个组合。

循环中 stack 的一个额外问题是它每次都会添加一个维度,并且需要匹配形状。

np.stack((foo,d3))  # a (2,3,3) with a (3,3); dimensions don't match
np.stack((foo,foo)) # produces (2,2,3,3)

要向 foo 添加更多数组,您必须将它们扩展为 (1,3,3) 形状

np.concatenate((foo, d3[None,:,:], d4[None,:,:]), axis=0)

然后将 (2,3,3) 与 (1,3,3) 和另一个 (1,3,3) 等连接起来;除第一个维度之外的匹配维度。

使用这些函数中的任何一个连接数组时,您不能对维度随意。 np.concatenate 有关于它可以组合的非常具体的规则。