Numpy数组的组合与分割详解
在介绍数组的组合和分割前,我们需要先了解数组的维(ndim)和轴(axis)概念。
如果数组的元素是数组,即数组嵌套数组,我们就称其为多维数组。几层嵌套就称几维。比如形状为(a,b)的二维数组就可以看作两个一维数组,第一个一维数组包含a个一维数组,第二个一维数组包含b个数据。
每一个一维线性数组称为一个轴。二维数组的第一个轴(axis=0)就是以数组为元素的数组,第二个轴(axis=1)就是数组中的数组。因此第一个轴的方向就是沿着列的方向,第二个轴的方向沿着行的方向。
这似乎有点反直觉,毕竟我们做数组切片时是先沿着行的方向,再沿着列的方向。但我们从嵌套数组的角度来看,a[0],a[1],a[2],a[3]……分别是取二维数组的第一行,二行,三行,四行……这正是先沿着第一个轴取元素(元素为行)。a[0][0],a[0][1]……则是(沿着第二个轴)取第一行的第一个元素,第二个元素……
也就是说,数组的轴从最外层数起。
三维数组我们应该怎么理解呢?我们可以把它看作二维数组的堆叠,即一个立方体。它的第一个轴(axis=0)就是以二维数组为元素的数组,它的方向沿着二维数组堆叠的方向,也就是立方体的高。第二个轴自然就是立方体的宽,第三个轴就是立方体的长。举例来说,一个形状为(a,b,c)的三维数组就是三个形状为(b,c)的二维数组嵌套在一起。
点击查看代码
a=np.arange(24).reshape(2,3,4)#建立一个维度为3,形状为(2,3,4)的三维数组
print(a)#打印
print(a.sum(axis=0))#沿第一个轴求和
print(a.sum(axis=1))#沿第二个轴求和
print(a.sum(axis=2))#沿第三个轴求和
'''
a的形状如下:
[[[ 0 1 2 3]
[ 4 5 6 7]
[ 8 9 10 11]]
[[12 13 14 15]
[16 17 18 19]
[20 21 22 23]]]
沿第一个轴求和:
[[12 14 16 18]
[20 22 24 26]
[28 30 32 34]]
沿第二个轴求和:
[[12 15 18 21]
[48 51 54 57]]
沿第三个轴求和:
[[ 6 22 38]
[54 70 86]]
'''
从这个例子可以看出,沿第一个轴求和,就是从上方把这个立方体“压扁”,第二个轴就是沿着宽,第三个轴就是沿着长。类似投影。
我们终于明白了,reshape函数的参数顺序不是我们想当然认为的长,宽;长,宽,高;因为你无法解释为什么三维数组变形后的形状与你所想的大相径庭。它的顺序是轴的顺序(第一条轴,第二条轴,第三条轴……),也就是沿这条轴有多少个元素。轴的概念很重要,在很多函数中都有体现。
再直观一点说,参数顺序应该是高,宽(行),长(列)。
所以,数组的维度就很好理解了,就是轴的数量。我们在理解多维数组的时候,不要先入为主地认为多维数组的元素会更多;多维数组只是它嵌套的层数多而已。高维数组也可能只含一个元素。
接下来我们介绍数组的组合。
数组的组合
数组的组合有水平组合,垂直组合,深度组合等方式。实现这些组合的函数主要有vstack,dstack,hstack,column_stack,row_stack,concatenate等。
因为我们最常用的数组也不过三维,所以用水平,垂直这样的字眼比较形象;但我们要明白,本质上是沿轴进行的操作。
数组组合通常不会改变数组的维度。
1.水平组合
hstack函数与concatenate函数
1.1hstack函数:水平连接多个数组。参数只有一个:以数组为元素的序列。
1.2concatenate函数:沿着现有的轴连接数组序列。
函数格式:concatenate((a1, a2, ...), axis=0, out=None)
参数说明:a1, a2, ...:为以数组为元素的类数组序列。其中数组形状必须相同。
axis=0:数组将沿着这个轴组合,如果坐标轴为None,数组在使用前被平铺。int型数据,可选参数,默认为零。
2.垂直组合
vstack函数与concatenate函数
2.1vstack函数:垂直连接多个数组。参数如上。
2.2concatenate函数改一下参数就好。
应当说明的是,水平组合和垂直组合是比较直观的说法,因为我们用的最多的数组就是一维和二维;实际上,它们分别是沿着第二条轴(水平),第一条轴(垂直)进行组合。
点击查看代码
a=np.array([1])
a=a.reshape(1,1,1,1,1)#只有一个元素的五维数组
b=np.array([1])
b=b.reshape(1,1,1,1,1)#与a完全相同
c=np.hstack((a,b))#水平组合
d=np.vstack((a,b))#垂直组合
print(c)
print(d)
print(c.shape)
print(d.shape)
'''
水平组合
[[[[[1]]]
[[[1]]]]]
垂直组合
[[[[[1]]]]
[[[[1]]]]]
c的形状
(1, 2, 1, 1, 1)
d的形状
(2, 1, 1, 1, 1)
'''
3.行组合和列组合
3.1row_stack函数:行组合
将一维数组按行方向组合起来,对于二维数组完全等同于vstack。对于多维数组,实际上就是沿第一个轴进行组合。
3.2colum_stack函数:列组合
将一维数组按列方向组合起来,对于二维数组完全等同于hstack。对于多维数组,实际上就是沿第二个轴进行组合。
点击查看代码
a=np.array([0,1,2])
b=np.array([1,2,3])
c=np.row_stack((a,b))
d=np.column_stack((a,b))
print(c)
print(d)
'''
行组合
[[0 1 2]
[1 2 3]]
列组合
[[0 1]
[1 2]
[2 3]]
'''
a=np.array([0,1,2]).reshape(1,1,1,1,3)
b=np.array([1,2,3]).reshape(1,1,1,1,3)
c=np.row_stack((a,b))
d=np.column_stack((a,b))
print(c)
print(d)
print(c.shape)
print(d.shape)
'''
行组合
[[[[[0 1 2]]]]
[[[[1 2 3]]]]]
[[[[[0 1 2]]]
列组合
[[[1 2 3]]]]]
c形状
(2, 1, 1, 1, 3)
d形状
(1, 2, 1, 1, 3)
'''
4.深度组合
沿着第三个轴进行组合。
点击查看代码
a=np.array([0,1,2])
b=np.array([1,2,3])
c=np.dstack((a,b))#深度组合
print(c)
print(a.shape)
print(c.shape)
'''
[[[0 1]
[1 2]
[2 3]]]
(3,)
(1, 3, 2)
'''
a=np.array([0,1,2]).reshape(1,1,1,3)
b=np.array([1,2,3]).reshape(1,1,1,3)
c=np.dstack((a,b))
print(c.shape)
'''
(1, 1, 2, 3)
'''
当数组维度比较小的时候,比如一维和二维,如果组合时没有第二和第三参数,函数会自动为其在形状左侧补1,也就是拓展一层。这和之前说过的广播机制十分类似。
数组的分割
数组可以进行水平,垂直等方式进行分割。相关函数:hsplit,vsplit,dsplit,split。
我们可以将数组分割成相同大小(形状)的子数组,也可以指定分割的位置。
1.水平分割
hsplit函数和split函数。
沿水平方向,就是沿列方向,沿第二条轴(axis=1)方向。
1.1hsplit函数
格式:hsplit(ary, indices_or_sections)
第一个参数是数组;第二个参数是一个整数或列表,如果不指定,就会分割成相同大小的子数组。
点击查看代码
a=np.arange(16).reshape(4,4)
pp.pprint(a)
pp.pprint(np.hsplit(a,2))#平均分割成两部分
pp.pprint(np.hsplit(a,[2,3]))#沿第二,三列,分割成三部分
'''
array([[ 0, 1, 2, 3],
[ 4, 5, 6, 7],
[ 8, 9, 10, 11],
[12, 13, 14, 15]])
分割成两部分
[array([[ 0, 1],
[ 4, 5],
[ 8, 9],
[12, 13]]),
array([[ 2, 3],
[ 6, 7],
[10, 11],
[14, 15]])]
分割成三部分
[array([[ 0, 1],
[ 4, 5],
[ 8, 9],
[12, 13]]),
array([[ 2],
[ 6],
[10],
[14]]),
array([[ 3],
[ 7],
[11],
[15]])]
'''
1.2split函数
函数格式:split(ary, indices_or_sections, axis=0)
第一个参数:数组。
第二个参数:整数或列表,可选参数。
第三个参数:轴,可选参数。
点击查看代码
a=np.arange(24).reshape(4,6)
print(a)
pp.pprint(np.split(a,[2],axis=0))
'''
[[ 0 1 2 3 4 5]
[ 6 7 8 9 10 11]
[12 13 14 15 16 17]
[18 19 20 21 22 23]]
[array([[ 0, 1, 2, 3, 4, 5],
[ 6, 7, 8, 9, 10, 11]]),
array([[12, 13, 14, 15, 16, 17],
[18, 19, 20, 21, 22, 23]])]
'''
上面这个例子里,我们选择了第一条轴,也就是列方向。然后找到第二行一分为二。
点击查看代码
点击查看代码
a=np.arange(24).reshape(2,3,4)
print(a)
pp.pprint(np.split(a,[1],axis=0))#沿第一条轴,高
pp.pprint(np.split(a,[1],axis=1))#沿第二条轴,宽
pp.pprint(np.split(a,[1],axis=2))#沿第三条轴,长
'''
[[[ 0 1 2 3]
[ 4 5 6 7]
[ 8 9 10 11]]
[[12 13 14 15]
[16 17 18 19]
[20 21 22 23]]]
[array([[[ 0, 1, 2, 3],
[ 4, 5, 6, 7],
[ 8, 9, 10, 11]]]),
array([[[12, 13, 14, 15],
[16, 17, 18, 19],
[20, 21, 22, 23]]])]
[array([[[ 0, 1, 2, 3]],
[[12, 13, 14, 15]]]),
array([[[ 4, 5, 6, 7],
[ 8, 9, 10, 11]],
[[16, 17, 18, 19],
[20, 21, 22, 23]]])]
[array([[[ 0],
[ 4],
[ 8]],
[[12],
[16],
[20]]]),
array([[[ 1, 2, 3],
[ 5, 6, 7],
[ 9, 10, 11]],
[[13, 14, 15],
[17, 18, 19],
[21, 22, 23]]])]
'''
上面是一个三维数组切割的例子。
2.垂直分割
vsplit函数和split函数
沿垂直方向,就是沿行方向,沿第一条轴(axis=0)方向。
split函数如上,改一条轴参数即可。
3.深度分割
dsplit函数
主要用于三维数组,其实就是沿第三条轴切割,就好比从上方切蛋糕一样。
点击查看代码
a=np.arange(24).reshape(2,3,4)
b=np.dsplit(a,4)#把这个蛋糕从上切成四份
pp.pprint(b)
'''
[array([[[ 0],
[ 4],
[ 8]],
[[12],
[16],
[20]]]),
array([[[ 1],
[ 5],
[ 9]],
[[13],
[17],
[21]]]),
array([[[ 2],
[ 6],
[10]],
[[14],
[18],
[22]]]),
array([[[ 3],
[ 7],
[11]],
[[15],
[19],
[23]]])]
'''
以上。
Numpy数组的组合与分割详解的更多相关文章
- 第15.41节、PyQt(Python+Qt)入门学习:输入部件QComboBox组合框功能详解
专栏:Python基础教程目录 专栏:使用PyQt开发图形界面Python应用 专栏:PyQt入门学习 老猿Python博文目录 一.概述 Designer中输入工具部件中的Combo Box组合框与 ...
- Java学习之二维数组定义与内存分配详解
二维数组:就是元素为一维数组的一个数组. 格式1: 数据类型[][] 数组名 = new 数据类型[m][n]; m:表示这个二维数组有多少个一维数组. n:表示每一个一维数组的元素有多少个. 注意: ...
- springmvc接收前台(如ajax)传来的数组list,set等图文详解
ref:https://blog.csdn.net/wabiaozia/article/details/50803581 前言: 相信很人都被springmvc接收数组问题折磨过,查过几个解决 ...
- c语言字符数组与字符串的使用详解
转自:http://www.jb51.net/article/37456.htm 1.字符数组的定义与初始化字符数组的初始化,最容易理解的方式就是逐个字符赋给数组中各元素.char str[10]={ ...
- 引用类型之数组array最全的详解
Array类型 今天总结一下array类型. js中的数组是有着非常强大的功能.具有很大的灵活性,有两个方面的特点 1.数组的每一项可以保存任何的数据类型:2.数组大小可以动态的调整:看下面的例子: ...
- JavaScript中数组Array.sort()排序方法详解
JavaScript中数组的sort()方法主要用于对数组的元素进行排序.其中,sort()方法有一个可选参数.但是,此参数必须是函数. 数组在调用sort()方法时,如果没有传参将按字母顺序(字符编 ...
- 第三十四章、PyQt中的输入部件:QComboBox组合框功能详解
专栏:Python基础教程目录 专栏:使用PyQt开发图形界面Python应用 专栏:PyQt入门学习 老猿Python博文目录 一.概述 Designer中输入工具部件中的Combo Box组合框与 ...
- JavaScript中数组Array方法详解
ECMAScript 3在Array.prototype中定义了一些很有用的操作数组的函数,这意味着这些函数作为任何数组的方法都是可用的. 1.Array.join()方法 Array.join()方 ...
- 20160205.CCPP体系详解(0015天)
程序片段(01):01.杨辉三角.c 内容概要:杨辉三角 #include <stdio.h> #include <stdlib.h> #define N 10 //01.杨辉 ...
随机推荐
- 常用API文字版
常用API Object类 jvm启动,默认导入的是java.lang包中的内容,该包下的内容不需要import进行导入. 概念 该类是java体系中的根类,所有对象都将该类作为直接或者间接父类 所有 ...
- 连接mysql数据库实现增删改查(一)
在python中我们通过pymysql来连接数据库,具体实现如下 ''' 连接mysql数据库 此类进行封装了一些基础的操作数据库方法 ''' import pymysql from Homework ...
- SpringBoot:WebSocket使用Service层的方法
方法一: 创建工具类 ApplicationContextRegister.java import org.springframework.beans.BeansException; import o ...
- Docker:docker安装部署jenkins
Docker安装步骤请转到:https://www.cnblogs.com/nhdlb/p/11262527.html 查看docker的jenkins镜像版本 #查看jenkins版本命令 dock ...
- vsftp安装错误总结
1.vsftpd 530 Login incorrect 解决办法:将用户从/etc/vsftpd/ftpusers 中删除 参考:http://blog.51yip.com/linux/1672. ...
- Java8 Map中新增的方法使用总结
前言 得益于 Java 8 的 default 方法特性,Java 8 对 Map 增加了不少实用的默认方法,像 getOrDefault, forEach, replace, replaceAll, ...
- ESP32 ADF windows开发环境搭建 适配ADF到ESP32A1S(转)
搭建ESP32A1S的ADF开发环境 一,获取IDF和IDF-TOOL adf是乐鑫的音频开发框架,里面有许多乐鑫的音频开发API,同时ADF是基于IDF的.这一部分可以按照官网的教程一步一步来.官网 ...
- IDEA工具-自动导包去除星号(import xx.xx.*)
打开设置>Editor>Code Style>Java>Scheme Default>Imports 设置导入类数值阈值,默认同包类是超过5个变成*,静态导入超过3个变成 ...
- elasticsearch常见错误及解决方案
1.OpenJDK 64-Bit Server VM warning: If the number of processors is expected to increase from one, th ...
- Odoo的附件大小限制
Odoo使用binary类型来保存附件数据,可以直接支持附件数据的上传.但是在实际使用中,有可能遇到附件文件大小超过限制的情况,如下图: 但是ERP定制过程中难免会遇到客户确实需要上传超大附件,那么怎 ...