☞ ░ 前往老猿Python博客 ░ https://blog.csdn.net/LaoYuanPython
一、引言
numpy的dstack函数用于沿着第三个维度(深度)将数组堆叠起来。它将多个数组按照深度方向进行堆叠,生成一个新的数组。具体来说,dstack函数会将输入的多个数组在第三个维度上进行拼接,即将每个数组的对应位置的元素组合成一个新的元素。

初学者在学习使用这个函数时,可能会有一些疑惑?所谓第三个维度是什么呢?假设对于一个数组a[n0,…,nx],当x大于等于2时,可以理解第三个维度为n2对应的维度,那怎么对x=1的二维数组也能堆叠呢?
二、数组的dstack堆叠测试
为了弄懂这个问题,老猿写了个测试程序,分别对一维、二维、三维、四维数组使用dstack进行测试,测试代码如下:
import numpy as np
a1 = np.array(range(36))
a2 = a1.reshape((9,4))
a3 = a1.reshape((3,3,4))
a4 = a1.reshape((3,3,2,2))
l1 = np.array([a1,a2,a3,a4])
l2 = l1+100
index = 0
for a,b in zip(l1,l2):
    c = np.dstack((a,b))
    print(f"\n****a{index}.shape={a.shape},a{index}:\n",a)
    print(f"\n****c{index}.shape={c.shape},c{index}:\n",c)
    index+=1
 
这个程序先创建一个 36个元素的一维数组,其值为0-35,然后用其为基础创建了2、3、4维的数组,将这些数组作为元素保存到一个l1的数组中好方便处理,然后将l1中每个数组的元素值加100保存到数组l2中,由于l1的所有数组最终维度的元素值为0-36,而l2的为100-136,这样就能方便识别最终输出数组的元素是来着那个数组。
程序输出如下:
****a0.shape=(36,),a0:
 [ 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 27 28 29 30 31 32 33 34 35]
****c0.shape=(1, 36, 2),c0:
 [[[  0 100]
  [  1 101]
  [  2 102]
  [  3 103]
  [  4 104]
  [  5 105]
  [  6 106]
  [  7 107]
  [  8 108]
  [  9 109]
  [ 10 110]
  [ 11 111]
  [ 12 112]
  [ 13 113]
  [ 14 114]
  [ 15 115]
  [ 16 116]
  [ 17 117]
  [ 18 118]
  [ 19 119]
  [ 20 120]
  [ 21 121]
  [ 22 122]
  [ 23 123]
  [ 24 124]
  [ 25 125]
  [ 26 126]
  [ 27 127]
  [ 28 128]
  [ 29 129]
  [ 30 130]
  [ 31 131]
  [ 32 132]
  [ 33 133]
  [ 34 134]
  [ 35 135]]]
****a1.shape=(9, 4),a1:
 [[ 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 27]
 [28 29 30 31]
 [32 33 34 35]]
****c1.shape=(9, 4, 2),c1:
 [[[  0 100]
  [  1 101]
  [  2 102]
  [  3 103]]
 [[  4 104]
  [  5 105]
  [  6 106]
  [  7 107]]
 [[  8 108]
  [  9 109]
  [ 10 110]
  [ 11 111]]
 [[ 12 112]
  [ 13 113]
  [ 14 114]
  [ 15 115]]
 [[ 16 116]
  [ 17 117]
  [ 18 118]
  [ 19 119]]
 [[ 20 120]
  [ 21 121]
  [ 22 122]
  [ 23 123]]
 [[ 24 124]
  [ 25 125]
  [ 26 126]
  [ 27 127]]
 [[ 28 128]
  [ 29 129]
  [ 30 130]
  [ 31 131]]
 [[ 32 132]
  [ 33 133]
  [ 34 134]
  [ 35 135]]]
****a2.shape=(3, 3, 4),a2:
 [[[ 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 27]
  [28 29 30 31]
  [32 33 34 35]]]
****c2.shape=(3, 3, 8),c2:
 [[[  0   1   2   3 100 101 102 103]
  [  4   5   6   7 104 105 106 107]
  [  8   9  10  11 108 109 110 111]]
 [[ 12  13  14  15 112 113 114 115]
  [ 16  17  18  19 116 117 118 119]
  [ 20  21  22  23 120 121 122 123]]
 [[ 24  25  26  27 124 125 126 127]
  [ 28  29  30  31 128 129 130 131]
  [ 32  33  34  35 132 133 134 135]]]
****a3.shape=(3, 3, 2, 2),a3:
 [[[[ 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 27]]
  [[28 29]
   [30 31]]
  [[32 33]
   [34 35]]]]
****c3.shape=(3, 3, 4, 2),c3:
 [[[[  0   1]
   [  2   3]
   [100 101]
   [102 103]]
  [[  4   5]
   [  6   7]
   [104 105]
   [106 107]]
  [[  8   9]
   [ 10  11]
   [108 109]
   [110 111]]]
 [[[ 12  13]
   [ 14  15]
   [112 113]
   [114 115]]
  [[ 16  17]
   [ 18  19]
   [116 117]
   [118 119]]
  [[ 20  21]
   [ 22  23]
   [120 121]
   [122 123]]]
 [[[ 24  25]
   [ 26  27]
   [124 125]
   [126 127]]
  [[ 28  29]
   [ 30  31]
   [128 129]
   [130 131]]
  [[ 32  33]
   [ 34  35]
   [132 133]
   [134 135]]]]
 
三、结论
从上面的程序和输出来看,dstack在进行数组堆叠时有如下结论:
- 不但能堆叠三维以上数组,而且能堆叠一维和二维数组;
 - 对三维以上数组堆叠时,结果数组的维度数保持不变;三维以上数组堆叠时,取两个参与堆叠数组的第三个维度的元素进行堆叠(元素合并)处理,堆叠后第三个维度的元素为参与堆叠的两个数组第三个维度的合并,因此个数翻倍,其他维度保持不变;
 - 对二维数组堆叠时,堆叠结果为三维数组,前面两个维度大小就是参与堆叠的两个数组的维度大小,最后一个维度大小固定为2; 二维数组堆叠时,堆叠结果的第三个维度的元素为参与堆叠的两个数组第二个维度的元素按顺序逐一各取一个构成数组作为结果数组第三个维度对应位置的元素;
 - 对一维数组堆叠时,堆叠结果为三维数组,第一个维度大小就是参与堆叠的两个数组的维度大小,第二个维度的大小固定为1,最后一个维度大小固定为2;一维数组堆叠时,堆叠结果的第三个维度的元素为参与堆叠的两个数组的元素按顺序逐一各取一个构成数组作为结果数组第三个维度对应位置的元素。
 
如果诸君对以上描述存在疑问,请结合上面的案例进行对比验证。
如对文章内容存在疑问或需要相关资料,可在博客评论区留言,或关注:老猿Python 微信公号发消息咨询,可通过扫二维码加微信公众号。
写博不易,敬请支持:
如果阅读本文于您有所获,敬请点赞、评论、收藏,谢谢大家的支持!
关于老猿的付费专栏
- 付费专栏《https://blog.csdn.net/laoyuanpython/category_9607725.html 使用PyQt开发图形界面Python应用》专门介绍基于Python的PyQt图形界面开发基础教程,对应文章目录为《 https://blog.csdn.net/LaoYuanPython/article/details/107580932 使用PyQt开发图形界面Python应用专栏目录》;
 - 付费专栏《https://blog.csdn.net/laoyuanpython/category_10232926.html moviepy音视频开发专栏 )详细介绍moviepy音视频剪辑合成处理的类相关方法及使用相关方法进行相关剪辑合成场景的处理,对应文章目录为《https://blog.csdn.net/LaoYuanPython/article/details/107574583 moviepy音视频开发专栏文章目录》;
 - 付费专栏《https://blog.csdn.net/laoyuanpython/category_10581071.html OpenCV-Python初学者疑难问题集》为《https://blog.csdn.net/laoyuanpython/category_9979286.html OpenCV-Python图形图像处理 》的伴生专栏,是笔者对OpenCV-Python图形图像处理学习中遇到的一些问题个人感悟的整合,相关资料基本上都是老猿反复研究的成果,有助于OpenCV-Python初学者比较深入地理解OpenCV,对应文章目录为《https://blog.csdn.net/LaoYuanPython/article/details/109713407 OpenCV-Python初学者疑难问题集专栏目录 》
 - 付费专栏《https://blog.csdn.net/laoyuanpython/category_10762553.html Python爬虫入门 》站在一个互联网前端开发小白的角度介绍爬虫开发应知应会内容,包括爬虫入门的基础知识,以及爬取CSDN文章信息、博主信息、给文章点赞、评论等实战内容。
 
前两个专栏都适合有一定Python基础但无相关知识的小白读者学习,第三个专栏请大家结合《https://blog.csdn.net/laoyuanpython/category_9979286.html OpenCV-Python图形图像处理 》的学习使用。
对于缺乏Python基础的同仁,可以通过老猿的免费专栏《https://blog.csdn.net/laoyuanpython/category_9831699.html 专栏:Python基础教程目录)从零开始学习Python。
如果有兴趣也愿意支持老猿的读者,欢迎购买付费专栏。


















