4.1 NumPy的ndarray一种多维数组对象
数组转置和轴对换
转置是重塑的一种特殊形式,它返回的是源数据的视图(不会进行任何复制操作)。
数组不仅有transpose方法,还有一个特殊的T属性:
In [126]: arr = np.arange(15).reshape((3, 5))
In [127]: arr
Out[127]:
array([[ 0, 1, 2, 3, 4],
[ 5, 6, 7, 8, 9],
[10, 11, 12, 13, 14]])
In [128]: arr.T
Out[128]:
array([[ 0, 5, 10],
[ 1, 6, 11],
[ 2, 7, 12],
[ 3, 8, 13],
[ 4, 9, 14]])
对于高维数组,transpose方法,需要得到一个由轴编号组成的元组才能对这些轴进行转置(比较费脑子):
transpose
方法是数组用来转置的一种方法,尤其对于高维数组,transpose
需要得到一个由轴编号组成的元组才能对这些轴进行转置。那么是怎么根据这个轴来完成转置的呢?
举个栗子:
举例说明:先创建一个2*2*4的三维数组:
In [59]: arrrr=np.arange(16).reshape((2,2,4))
In [60]: arrrr
Out[60]:
array([[[ 0, 1, 2, 3],
[ 4, 5, 6, 7]],
[[ 8, 9, 10, 11],
[12, 13, 14, 15]]])
我假设这个三维数组在空间中按上图的方式排列,数组里每个数字存放在一个小立方体中
更具体一点,我们的俯视图如下:
用表格展示这个数组arr,如下:
长0 | 长1 | 长2 | 长3 | |
高0.宽0 | 0 | 1 | 2 | 3 |
高0.宽1 | 4 | 5 | 6 | 7 |
长0 | 长1 | 长2 | 长3 | |
高1.宽0 | 8 | 9 | 10 | 11 |
高1.宽1 | 12 | 13 | 14 | 15 |
长0 | 长1 | 长2 | 长3 | |
高0.宽0 | 0 | 1 | 2 | 3 |
高0.宽1 | 8 | 9 | 10 | 11 |
长0 | 长1 | 长2 | 长3 | |
高1.宽0 | 4 | 5 | 6 | 7 |
高1.宽1 | 12 | 13 | 14 | 15 |
接着转化为坐标及对应的值,如下:
坐标 | 值 |
0.0.0 | 0 |
0.0.1 | 1 |
0.0.2 | 2 |
0.0.3 | 3 |
0.1.0 | 4 |
0.1.1 | 5 |
0.1.2 | 6 |
0.1.3 | 7 |
1.0.0 | 8 |
1.0.1 | 9 |
1.0.2 | 10 |
1.0.3 | 11 |
1.1.0 | 12 |
1.1.1 | 13 |
1.1.2 | 14 |
1.1.3 | 15 |
这也是数组取值时使用的坐标,例如:(1,0,0)对应8
In [60]: arrrr
Out[60]:
array([[[ 0, 1, 2, 3],
[ 4, 5, 6, 7]],
[[ 8, 9, 10, 11],
[12, 13, 14, 15]]])
In [61]: arrrr[1,0,0]
Out[61]: 8
接下来,解释下整个转换的过程:
1.先定义需要被转化的数组(我们临时把他称为:原数组):
In [59]: arrrr=np.arange(16).reshape((2,2,4))
In [60]: arrrr
Out[60]:
array([[[ 0, 1, 2, 3],
[ 4, 5, 6, 7]],
[[ 8, 9, 10, 11],
[12, 13, 14, 15]]])
原数组arrrr=np.arange(16).reshape((2,2,4))
咱们先定义一下:
用reshape(参数0,参数1,参数2)方法创建的数组时,
给参数0起名(编号)为:0轴,给参数1起名(编号)为:1轴,给参数2起名(编号)为:2轴,
每个轴对应的数值叫做:轴的长度
那么reshape((2,2,4)就可以表达为:创建0轴长度为2,1轴长度为2,2轴长度为4的数组arrrr。
2.解释转换过程
transpose方法,需要得到一个由轴编号组成的元组才能对这些轴进行转置
注意这句话的重点:轴编号!!!
轴编号就是咱们上面给轴起的名字:0轴、1轴、2轴
也就是说transpose方法中的参数是:轴编号(也就是咱们的0轴、1轴、2轴)
当数组是3维数组时,在transpose()方法中,其实就是0轴、1轴、2轴对应的就是0,1,2,
transpose()方法只能是0,1,2不重复的组合排列
即:transpose((1,0,2)),transpose((2,0,1)),transpose((2,1,0)),transpose((1,2,0)),transpose((0,2,1)),transpose((0,1,2))
【注:transpose((0,1,2))不会改变数组,因为0,1,2,其实就是数组创建时轴编号的顺序
.reshape((2,2,4)),其实是创建了0轴长度为2,1轴长度为2,2轴长度为4的数组】
使用其他数字或者是数字重复都会报错
In [63]: arrrr.transpose((1,3,2))
---------------------------------------------------------------------------
AxisError Traceback (most recent call last)
<ipython-input-63-7a9f29aaebef> in <module>
----> 1 arrrr.transpose((1,3,2))
AxisError: axis 3 is out of bounds for array of dimension 3
In [64]: arrrr.transpose((1,1,2))
---------------------------------------------------------------------------
ValueError Traceback (most recent call last)
<ipython-input-64-01f32732ffe4> in <module>
----> 1 arrrr.transpose((1,1,2))
ValueError: repeated axis in transpose
In [65]: arrrr.transpose((1,0,1))
---------------------------------------------------------------------------
ValueError Traceback (most recent call last)
<ipython-input-65-778f0eb81639> in <module>
----> 1 arrrr.transpose((1,0,1))
ValueError: repeated axis in transpose
继续解释转换过程:
In [59]: arrrr=np.arange(16).reshape((2,2,4))
In [60]: arrrr
Out[60]:
array([[[ 0, 1, 2, 3],
[ 4, 5, 6, 7]],
[[ 8, 9, 10, 11],
[12, 13, 14, 15]]])
In [62]: arrrr.transpose((1,0,2))
Out[62]:
array([[[ 0, 1, 2, 3],
[ 8, 9, 10, 11]],
[[ 4, 5, 6, 7],
[12, 13, 14, 15]]])
因为创建数组时轴编号(0轴、1轴、2轴)的顺序默认就是(0,1,2)
所以arrrr.transpose((1,0,2))可以表达为:
将数组arrrr默认的(0轴、1轴、2轴)转换为(1轴、0轴、2轴),对应3维图就是“高宽互换”
3.得到转换后的数组
空间的转换比较难想象,我也没想,转换可以直接在,“坐标及对应值”的表中完成
即:原数组0轴那一列的内容和原数组1轴那一列的内容互换(值保持不变)就可得到转换后的数组
原数组 | 转换后的数组 | ||||||
0轴 | 1轴 | 2轴 | 值 | 0轴 | 1轴 | 2轴 | 值 |
0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
0 | 0 | 1 | 1 | 0 | 0 | 1 | 1 |
0 | 0 | 2 | 2 | 0 | 0 | 2 | 2 |
0 | 0 | 3 | 3 | 0 | 0 | 3 | 3 |
0 | 1 | 0 | 4 | 1 | 0 | 0 | 4 |
0 | 1 | 1 | 5 | 1 | 0 | 1 | 5 |
0 | 1 | 2 | 6 | 1 | 0 | 2 | 6 |
0 | 1 | 3 | 7 | 1 | 0 | 3 | 7 |
1 | 0 | 0 | 8 | 0 | 1 | 0 | 8 |
1 | 0 | 1 | 9 | 0 | 1 | 1 | 9 |
1 | 0 | 2 | 10 | 0 | 1 | 2 | 10 |
1 | 0 | 3 | 11 | 0 | 1 | 3 | 11 |
1 | 1 | 0 | 12 | 1 | 1 | 0 | 12 |
1 | 1 | 1 | 13 | 1 | 1 | 1 | 13 |
1 | 1 | 2 | 14 | 1 | 1 | 2 | 14 |
1 | 1 | 3 | 15 | 1 | 1 | 3 | 15 |
例子:
再举个例子说明下:先创建一个2*3*4的三维数组
In [27]: arr=np.arange(24).reshape((2,3,4))
In [28]: arr
Out[28]:
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]]])
用表格展示这个数组arr,如下:
长0 | 长1 | 长2 | 长3 | |
高0.宽0 | 0 | 1 | 2 | 3 |
高0.宽1 | 4 | 5 | 6 | 7 |
高0.宽2 | 8 | 9 | 10 | 11 |
长0 | 长1 | 长2 | 长3 | |
高1.宽0 | 12 | 13 | 14 | 15 |
高1.宽1 | 16 | 17 | 18 | 19 |
高1.宽2 | 20 | 21 | 22 | 23 |
接着转化为坐标及对应的值,如下:
0轴 | 1轴 | 2轴 | 值 |
0 | 0 | 0 | 0 |
0 | 0 | 1 | 1 |
0 | 0 | 2 | 2 |
0 | 0 | 3 | 3 |
0 | 1 | 0 | 4 |
0 | 1 | 1 | 5 |
0 | 1 | 2 | 6 |
0 | 1 | 3 | 7 |
0 | 2 | 0 | 8 |
0 | 2 | 1 | 9 |
0 | 2 | 2 | 10 |
0 | 2 | 3 | 11 |
1 | 0 | 0 | 12 |
1 | 0 | 1 | 13 |
1 | 0 | 2 | 14 |
1 | 0 | 3 | 15 |
1 | 1 | 0 | 16 |
1 | 1 | 1 | 17 |
1 | 1 | 2 | 18 |
1 | 1 | 3 | 19 |
1 | 2 | 0 | 20 |
1 | 2 | 1 | 21 |
1 | 2 | 2 | 22 |
1 | 2 | 3 | 23 |
接下来,进行转换的过程:
In [51]: arr
Out[51]:
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]]])
In [52]: arr.transpose(2,1,0)
Out[52]:
array([[[ 0, 12],
[ 4, 16],
[ 8, 20]],
[[ 1, 13],
[ 5, 17],
[ 9, 21]],
[[ 2, 14],
[ 6, 18],
[10, 22]],
[[ 3, 15],
[ 7, 19],
[11, 23]]])
arr.transpose(2,1,0)可以表达为:
将数组arrrr默认的(0轴、1轴、2轴)转换为(2轴、1轴、0轴),对应3维图就是“高长互换”
即:原数组0轴那一列的内容和原数组2轴那一列的内容互换(值保持不变)就可得到转换后的数组
原数组 | 转换后的数组(按值大小排列) | 转换后的数组(按位置排列) | |||||||||
0轴 | 1轴 | 2轴 | 值 | 0轴 | 1轴 | 2轴 | 值 | 0轴 | 1轴 | 2轴 | 值 |
0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
0 | 0 | 1 | 1 | 1 | 0 | 0 | 1 | 0 | 0 | 1 | 12 |
0 | 0 | 2 | 2 | 2 | 0 | 0 | 2 | 0 | 1 | 0 | 4 |
0 | 0 | 3 | 3 | 3 | 0 | 0 | 3 | 0 | 1 | 1 | 16 |
0 | 1 | 0 | 4 | 0 | 1 | 0 | 4 | 0 | 2 | 0 | 8 |
0 | 1 | 1 | 5 | 1 | 1 | 0 | 5 | 0 | 2 | 1 | 20 |
0 | 1 | 2 | 6 | 2 | 1 | 0 | 6 | 1 | 0 | 0 | 1 |
0 | 1 | 3 | 7 | 3 | 1 | 0 | 7 | 1 | 0 | 1 | 13 |
0 | 2 | 0 | 8 | 0 | 2 | 0 | 8 | 1 | 1 | 0 | 5 |
0 | 2 | 1 | 9 | 1 | 2 | 0 | 9 | 1 | 1 | 1 | 17 |
0 | 2 | 2 | 10 | 2 | 2 | 0 | 10 | 1 | 2 | 0 | 9 |
0 | 2 | 3 | 11 | 3 | 2 | 0 | 11 | 1 | 2 | 1 | 21 |
1 | 0 | 0 | 12 | 0 | 0 | 1 | 12 | 2 | 0 | 0 | 2 |
1 | 0 | 1 | 13 | 1 | 0 | 1 | 13 | 2 | 0 | 1 | 14 |
1 | 0 | 2 | 14 | 2 | 0 | 1 | 14 | 2 | 1 | 0 | 6 |
1 | 0 | 3 | 15 | 3 | 0 | 1 | 15 | 2 | 1 | 1 | 18 |
1 | 1 | 0 | 16 | 0 | 1 | 1 | 16 | 2 | 2 | 0 | 10 |
1 | 1 | 1 | 17 | 1 | 1 | 1 | 17 | 2 | 2 | 1 | 22 |
1 | 1 | 2 | 18 | 2 | 1 | 1 | 18 | 3 | 0 | 0 | 3 |
1 | 1 | 3 | 19 | 3 | 1 | 1 | 19 | 3 | 0 | 1 | 15 |
1 | 2 | 0 | 20 | 0 | 2 | 1 | 20 | 3 | 1 | 0 | 7 |
1 | 2 | 1 | 21 | 1 | 2 | 1 | 21 | 3 | 1 | 1 | 19 |
1 | 2 | 2 | 22 | 2 | 2 | 1 | 22 | 3 | 2 | 0 | 11 |
1 | 2 | 3 | 23 | 3 | 2 | 1 | 23 | 3 | 2 | 1 | 23 |
In [69]: arr6
Out[69]:
array([[[ 0, 12],
[ 4, 16],
[ 8, 20]],
[[ 1, 13],
[ 5, 17],
[ 9, 21]],
[[ 2, 14],
[ 6, 18],
[10, 22]],
[[ 3, 15],
[ 7, 19],
[11, 23]]])
In [70]: arr6[2,1,0]
Out[70]: 6
In [71]: arr6[0,2,1]
Out[71]: 20
部分内容转自:https://blog.csdn.net/weixin_34258078/article/details/88720271,多谢大神