转自 https://blog.csdn.net/csdn15698845876/article/details/73380803

这三个函数有些相似性,都是堆叠数组,里面最难理解的应该就是stack()函数了,我查阅了numpy的官方文档,在网上又看了几个大牛的博客,发现他们也只是把numpy文档的内容照搬,看完后还是不能理解,最后经过本人代码分析,算是理解了stack()函数增加维度的含义。以下内容我会用通俗易懂的语言解释,内容可能有点多,耐心看,如果哪里说的不对,欢迎纠正!

1. stack()函数 
函数原型为:stack(arrays, axis=0),arrays可以传数组和列表。axis的含义我下面会讲解,我们先来看个例子,然后我会分析输出结果。

>>>import numpy as np
>>>a=[[1,2,3],
[4,5,6]]
>>>print("列表a如下:")
>>>print(a) >>>print("增加一维,新维度的下标为0")
>>>c=np.stack(a,axis=0)
>>>print(c) >>>print("增加一维,新维度的下标为1")
>>>c=np.stack(a,axis=1)
>>>print(c)

输出:

列表a如下:
[[1, 2, 3], [4, 5, 6]]
增加一维,新维度下标为0
[[1 2 3]
[4 5 6]]
增加一维,新维度下标为1
[[1 4]
[2 5]
[3 6]]

首先这里arrays我传的是一个列表,现在我开始讲解这个stack()函数的意思,它就是对arrays里面的每个元素(可能是个列表,元组,或者是个numpy的数组)变成numpy的数组后,再对每个元素增加一维(至于维度加在哪里,是靠axis控制的),然后再把这些元素串起来(至于怎么串,我下面会说)。

arrays里面的每个元素必须形状是一样的,例如本例中列表a中的两个元素[1,2,3]和[4,5,6]的形状是一样的,如果把[4,5,6]换成[4,5] ,那么程序会报错!而axis代表的是在哪个维度上加一维,例如axis=0(它是默认的)代表的就是增加的这一维的下标为0,axis等于多少不是随便乱写的,如果参数arrays里面的每个元素是个1维的,那么调用stack()函数增加一维后会变成2维的,所以axis只能等于0和1(维度的下标是从0开始的),而参数axis=0和axis=1得到的结果是不一样的。

例如上面的代码中a列表中的第一个元素为[1,2,3],那么当axis=0的时候,就是在它的中括号外面再加一个中括号,变成[ [1,2,3] ](其实1,2,3之间是没有逗号的,因为stack()函数会先把参数arrays中的每个元素变成numpy的数组,数组之间是没有逗号的,看看上面的代码输出就知道了,这里大家明白就行,我为了方便讲解,下面还会加上逗号),这样最外面那层中括号才代表维度下标为0的那维;当axis=1的时候,就是在里面加个中括号,变成了[ [1],[2],[3] ],这样里面加的那层中括号才代表维度下标为1的那维。同理当axis=0的时候[4,5,6]变成[ [ 4,5,6] ],当axis=1的时候,变成[ [4],[5],[6] ]。下面我们讲如何把增加一维度后的每个元素串起来。

怎么把上面那两个元素增加维度后的结果串起来呢,其实很简单。现在我们已经知道了增加维度无非是增加中括号的意思,至于在哪里加中括号,取决于axis等于几。我们把增加的中括号想像成一个个的箱子。还拿上面的代码来说,当axis=0的时候,我们把套在[1,2,3]外面的中括号(就是[ [1,2,3] ]最外层的那个中括号)看做是箱子A,这个箱子A也会套在[4,5,6]的外面,所以我们就先把[1,2,3]和[4,5,6]放在一起,变成[1,2,3],[4,5,6],然后再一起套上箱子A,变成[ [1,2,3],[4,5,6] ]这就是当axis=0的时候程序的输出结果。

现在再来看当axis=1的时候,对于[1,2,3],我们把套在1外面的箱子(就是上面讲的[ [1],[2],[3] ]中1外面的那层中括号)看做A,套在2外面的看做B,套在3外面的看做C,同理,箱子A也会套在4的外面,箱子B也会套在5的外面,箱子C也会套在6的外面。那么我们就把1和4放一起,2和5放一起,3和6放一起,变成[ 1,4 ,2,5 ,3,6 ]然后把箱子A,B,C分别套在1,4 , 2,5 , 3,6的外面,变成[ [1,4] , [2,5] , [3,6] ]这就是程序中axis=1的时候程序的输出结果。

大家发现了没有,串起来的时候其实就是把arrays中每个元素在相同的位置套箱子的一些小块(这里叫小块这个名词可能不洽当,但是大家明白就行)放在一起后,再套箱子,就是外面套个中括号,这就是堆叠。

再看下面的代码的输出,测试下你理解的没有。

>>>import numpy as np
>>>a=[[1,2,3,4],
[5,6,7,8],
[9,10,11,12]]
>>>print("列表a如下:")
>>>print(a) >>>print("增加一维,新维度的下标为0")
>>>c=np.stack(a,axis=0)
>>>print(c) >>>print("增加一维,新维度的下标为1")
>>>c=np.stack(a,axis=1)
>>>print(c)

输出:

列表a如下:
[[1, 2, 3, 4], [5, 6, 7, 8], [9, 10, 11, 12]]
增加一维,新维度的下标为0
[[ 1 2 3 4]
[ 5 6 7 8]
[ 9 10 11 12]]
增加一维,新维度的下标为1
[[ 1 5 9]
[ 2 6 10]
[ 3 7 11]
[ 4 8 12]]

不知道和你想象的输出一样不一样,还有另一种情况,先看下面的代码。

>>>import numpy as np
>>>a=[1,2,3,4]
>>>b=[5,6,7,8]
>>>c=[9,10,11,12]
>>>print("a=",a)
>>>print("b=",b)
>>>print("c=",c) >>>print("增加一维,新维度的下标为0")
>>>d=np.stack((a,b,c),axis=0)
>>>print(d) >>>print("增加一维,新维度的下标为1")
>>>d=np.stack((a,b,c),axis=1)
>>>print(d)

输出:

('a=', [1, 2, 3, 4])
('b=', [5, 6, 7, 8])
('c=', [9, 10, 11, 12])
增加一维,新维度的下标为0
[[ 1 2 3 4]
[ 5 6 7 8]
[ 9 10 11 12]]
增加一维,新维度的下标为1
[[ 1 5 9]
[ 2 6 10]
[ 3 7 11]
[ 4 8 12]]

你会发现输出结果和上面的代码一样,其实它俩就是一样的。只不过当你对arrays传参的时候,如果你传的参数是类似于(a,b,c)这种,它会把(a,b,c)当做一个元组来看,a,b,c都是元组的每个元素。然后分别对每个元素处理,上面我已经说了,arrays传的参数可以是列表,元组,或者numpy数组。所以传(a,b,c)和传[a,b,c]或者当x=[a,b,c]的时候传x,效果都是一样的。

上面的代码处理的arrays元素都是一维变二维的情况,下面我们看看二维变三维是什么样的。

import numpy as np
a=[[1,2,3],
[4,5,6]]
b=[[1,2,3],
[4,5,6]]
c=[[1,2,3],
[4,5,6]]
print("a=",a)
print("b=",b)
print("c=",c) print("增加一维,新维度的下标为0")
d=np.stack((a,b,c),axis=0)
print(d) print("增加一维,新维度的下标为1")
d=np.stack((a,b,c),axis=1)
print(d)
print("增加一维,新维度的下标为2")
d=np.stack((a,b,c),axis=2)
print(d)

输出:

('a=', [[1, 2, 3], [4, 5, 6]])
('b=', [[1, 2, 3], [4, 5, 6]])
('c=', [[1, 2, 3], [4, 5, 6]])
增加一维,新维度的下标为0
[[[1 2 3]
[4 5 6]] [[1 2 3]
[4 5 6]] [[1 2 3]
[4 5 6]]]
增加一维,新维度的下标为1
[[[1 2 3]
[1 2 3]
[1 2 3]] [[4 5 6]
[4 5 6]
[4 5 6]]]
增加一维,新维度的下标为2
[[[1 1 1]
[2 2 2]
[3 3 3]] [[4 4 4]
[5 5 5]
[6 6 6]]]

当axis=0的时候,列表a,b,c最外面都需要套箱子(就是加中括号),那么我把你们先放一起,变成下面这样

[[1,2,3],[4,5,6]],
[[1,2,3],[4,5,6]],
[[1,2,3],[4,5,6]]

然后在最外面套箱子,变成

[
[[1,2,3],[4,5,6]],
[[1,2,3],[4,5,6]],
[[1,2,3],[4,5,6]]
]

当axis=1的时候,列表a,b,c中的[1,2,3]需要套同样的箱子,列表a,b,c中的[4,5,6]需要套同样的箱子,好,我先把你们放一块变成下面这样

[
[1,2,3],[1,2,3],[1,2,3]
,
[4,5,6],[4,5,6],[4,5,6]
]

然后开始分别在 [1,2,3],[1,2,3],[1,2,3]的外面和[4,5,6],[4,5,6],[4,5,6]的外面套箱子,变成下面这样

[
[[1,2,3],[1,2,3],[1,2,3]]
,
[[4,5,6],[4,5,6],[4,5,6]]
]

当axis=2的时候,列表a,b,c中的1,2,3,4,5,6都需要套箱子,我把你们先放一起变成:

[
[1,1,1 , 2,2,2 , 3,3,3],
[4,4,4 , 5,5,5 , 6,6,6]
]

然后在1,1,1 ………6,6,6的外面分别套箱子变成:

[
[[1,1,1] , [2,2,2] , [3,3,3]],
[[4,4,4] , [5,5,5] , [6,6,6]]
]

关于stack()函数就讲这么多,这也是我全部理解的部分。

2. hstack()函数 
函数原型:hstack(tup) ,参数tup可以是元组,列表,或者numpy数组,返回结果为numpy的数组。看下面的代码体会它的含义

import numpy as np
a=[1,2,3]
b=[4,5,6]
print(np.hstack((a,b)))
输出:
[1 2 3 4 5 6 ]

import numpy as np
a=[[1],[2],[3]]
b=[[1],[2],[3]]
c=[[1],[2],[3]]
d=[[1],[2],[3]]
print(np.hstack((a,b,c,d)))

输出:

[[1 1 1 1]
[2 2 2 2]
[3 3 3 3]]

它其实就是水平(按列顺序)把数组给堆叠起来,vstack()函数正好和它相反。

3. vstack()函数 
函数原型:vstack(tup) ,参数tup可以是元组,列表,或者numpy数组,返回结果为numpy的数组。看下面的代码体会它的含义

import numpy as np
a=[1,2,3]
b=[4,5,6]
print(np.vstack((a,b)))
输出:
[[1 2 3]
[4 5 6]]

import numpy as np
a=[[1],[2],[3]]
b=[[1],[2],[3]]
c=[[1],[2],[3]]
d=[[1],[2],[3]]
print(np.vstack((a,b,c,d)))

输出:

[[1]
[2]
[3]
[1]
[2]
[3]
[1]
[2]
[3]
[1]
[2]
[3]]

它是垂直(按照行顺序)的把数组给堆叠起来。

【python】Numpy中stack(),hstack(),vstack()函数详解的更多相关文章

  1. python golang中grpc 使用示例代码详解

    python 1.使用前准备,安装这三个库 pip install grpcio pip install protobuf pip install grpcio_tools 2.建立一个proto文件 ...

  2. linux内核中send与recv函数详解

    Linux send与recv函数详解 1.简介 #include <sys/socket.h> ssize_t recv(int sockfd, void *buff, size_t n ...

  3. Numpy中stack(),hstack(),vstack()函数详解

    一`.stack 按指定维度堆叠数组.      stack(a, b) 维度计算 axis=0: 2*m*n axis=1:  m*2*n axis=-1: m*n*2 a = np.arange( ...

  4. Python中的next()\iter()函数详解

    什么是可迭代的对象(Iterable,即可以用for循环的对象)和迭代器(Iterator) Iterable: 一类是:list.tuple.dict.set.str 二类是:generator(都 ...

  5. 第8.14节 Python类中内置方法__str__详解

    一. object类内置方法__str__和函数str 类的内置方法__str__和内置函数str实际上实现的是同一功能,实际上str调用的就是__str__方法,只是调用方式不同,二者的调用语法如下 ...

  6. 第8.13节 Python类中内置方法__repr__详解

    当我们在交互环境下输入对象时会直接显示对象的信息,交互环境下输入print(对象)或代码中print(对象)也会输出对象的信息,这些输出信息与两个内置方法:__str__方法和__repr__方法有关 ...

  7. linux中fork()函数详解(原创!!实例讲解) (转载)

     一.fork入门知识 一个进程,包括代码.数据和分配给进程的资源.fork()函数通过系统调用创建一个与原来进程几乎完全相同的进程, 也就是两个进程可以做完全相同的事,但如果初始参数或者传入的变量不 ...

  8. (转)linux中fork()函数详解

    一.fork入门知识 一个进程,包括代码.数据和分配给进程的资源.fork()函数通过系统调用创建一个与原来进程几乎完全相同的进程,也就是两个进程可以做完全相同的事,但如果初始参数或者传入的变量不同, ...

  9. linux中fork()函数详解

    一.fork入门知识 一个进程,包括代码.数据和分配给进程的资源.fork()函数通过系统调用创建一个与原来进程几乎完全相同的进程,也就是两个进程可以做完全相同的事,但如果初始参数或者传入的变量不同, ...

随机推荐

  1. hdu6129 Just Do It!

    多校时找规律做过... 题意,给你一个数列a[1], a[2], a[3], a[4], ... , a[n],操作一次后变为a[1], a[1] ^ a[2], a[1] ^ a[2] ^ a[3] ...

  2. 完美解决xhost +报错: unable to open display "" 装oracle的时候总是在弹出安装界面的时候出错

    详细很多朋友在装oracle的时候总是在弹出安装界面的时候出错,界面就是蹦不出来. oracle安装 先切换到root用户,执行xhost + 然后再切换到oracle用户,执行export DISP ...

  3. 从swap说引用

    C++的引用类型是个很奇妙的存在,比如下面这个例子: #include<iostream> using namespace std; void swap(int& a, int&a ...

  4. day08_python_1124

    01 昨日内容回顾 文件操作 文件操作的流程: 1,打开文件创建文件句柄. 2,对文件句柄进行操作. 3,关闭文件句柄. 读, r r+ rb r+b read() 全部读取 read(n) 读取一部 ...

  5. unity中鼠标左键控制摄像机视角上下左右移动

    enum RotationAxes { MouseXAndY, MouseX, MouseY } RotationAxes axes = RotationAxes.MouseXAndY; //@Hid ...

  6. 羽翼metasploit第一,二季学习笔记

    -----------------第一季-------------------- 启动Metasploit:msfconsole 升级和更新:./msfupdate 直接退出:exit 退回上一级:q ...

  7. 复制目录及其子目录下所有文件DOC

    echo 开始同步代码 set src_home=F:\work\sign\Bonade-Sign set dest_home=F:\work\testGit\sign5\Bonade-Sign se ...

  8. spring boot 常见的配置问题

    最近在自学spring boot ,新手教程网上很多,这里主要记录下配置过程中的一些疑难杂症.这些记录都是针对以下配置生成的项目 1.该项目一定要用jdk1.8 2.application.prope ...

  9. oh_my_zsh

    oh_my_zsh  zsh默认已经安装   cat /etc/shells   查看安装没有   (https://xiaozhou.net/learn-the-command-line-iterm ...

  10. idea护眼设置

    idea护眼设置 看了很多intelliJ IDEA的配置文章,不知道大家为什么都不约而同的选择了黑色的那个主题,是很有感觉,很有程序猿的范.但是个人感觉对眼睛不太好,所以我还是用正常的框,建议大家把 ...