0 参考资料
[1] numpy中的transpose函数使用方法 - 学弟1 - 博客园 (cnblogs.com)
说明:本文的图片与代码基本改编或引用自'numpy中的transpose函数使用方法 - 学弟1 - 博客园 (cnblogs.com)'
1 二维数组
二维数组执行transpose(1,0)相当于执行矩阵的转置。transpose(1,0)可以简写为a.T或者a.transpose()
import numpy as np
arr = np.arange(15).reshape((3, 5))
print(arr)
print()
c = arr.T
print(c)
print()
a = arr.transpose()
print(a)
print()
b = arr.transpose(1, 0)
print(b)
输出为:
[[ 0 1 2 3 4]
[ 5 6 7 8 9]
[10 11 12 13 14]]
[[ 0 5 10]
[ 1 6 11]
[ 2 7 12]
[ 3 8 13]
[ 4 9 14]]
[[ 0 5 10]
[ 1 6 11]
[ 2 7 12]
[ 3 8 13]
[ 4 9 14]]
[[ 0 5 10]
[ 1 6 11]
[ 2 7 12]
[ 3 8 13]
[ 4 9 14]]
2 三维数组
理解三维数组的transpose()操作之前需要理解轴以及三维数组的概念。
2.1 三维数组
由p个m*n尺寸的二维数组组成的数组叫三维数组。下图所示的数组由2个3*4的二维数组构成,因此它是一个2*(3*4)结构的三维数组。
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]]])
下面教给大家一个快速判断三维数组结构的方法:
(1)计算“("与第一个数字之间共有多少个“[”,有几个“[”,就是几维数组,上图的“("与第一个数字"0"之间共有三个“[”,那么就是三维数组;
(2)找到第一个"]]"出现的位置,在此符号出现之前还有一个"[["符号,两个符号连在一起成为“[[ ]]”,这表示一个二维数组;
(3)找出“[[ ]]”内部有多少个数字的左边存在“[”,上图有三个数字(0,4,8)的左边都有“[”,因此数字3就是二维数组的行数;
(4)找出“[[ ]]”内部的一个最小的"[ ]"结构(最小的含义是[ ]内部不能包含“[“或者”]“),比如[0,1,2,3],数一数“[ ]”中有几个数字,上图是4个,那么数字4就是二维数组的列数;
(5)数一数最外层的"[]"包含几个((2)到(4)步骤这样的二维数组,上图是2个。
经过上述五个步骤,便可以得到上图所示的三维数组是由2个3*4的二维数组组成,其结构为2*(3*4)
2.2 轴的概念
简单来说轴0就是最外面的中括号包含的部分,轴1是倒数第二层中括号包含的部分,轴2是倒数第三层中括号包含的部分,其余轴依次类推。具体到三维数组,轴0,1,2包含的部分如下图所示:
2.3 transpose(1,0,2)
transpose(1,0,2)中的数字1,0,2表示这个结构为2*3*4的三维数组的轴1,轴0与轴2。transpose(1,0,2)表示将轴0与轴1交换位置(如下图所示,交换后出现了两个轴0)。轴1与轴0交换位置后,三维数组的结构也会从2*3*4变为3*2*4。
数组结构由2*3*4变为3*2*4后,注意到数字4的位置是没有发生改变的,也就是轴2不变(如上图所示)。轴二不变意味着0,1,2,3/4,5,6,7/8,9,10,11等数据的排列方式不变。比如1的左右两边只能是0与2,但是经过变换后0,1,2,3这一组数据的下边可能不再是4,5,6,7,而变成了12,13,14,15等元素。
原来的三维数组由2个3*4的二维数组构成,现在变成了由3个2*4的二维数组构成。也就是说0,1,2,3/4,5,6,7/8,9,10,11等数据的组合方式改变了,原来是0,1,2,3/4,5,6,7/8,9,10,11为一组,这一组构成一个二维数组;12,13,14,15/16,17,1819/20,21,22,23为一组,这一组构成第二个二维数组。现在需要将这些数据重新排布,新的排布方式为:两个轴0部分的第一行组合成为第一个二维数组([[ 0 ,1 ,2 ,3],[12, 13 ,14 ,15]]),轴0部分的第二行组合成为第二个二维数组([[ 4, 5, 6, 7] ,[16 ,17 ,18, 19]]),轴0部分的第三行组合成为第三个二维数组([[ 8, 9 ,10, 11], [20 ,21 ,22 ,23]])
将这三个二维数组放在一起,便可得到最终结果:
import numpy as np
arr = np.arange(24).reshape((2,3,4))
vc = arr.transpose(1,0,2)
print(vc)
>>>结果
[[[ 0 1 2 3]
[12 13 14 15]]
[[ 4 5 6 7]
[16 17 18 19]]
[[ 8 9 10 11]
[20 21 22 23]]]
2.4 transpose(0,2,1)
transpose(0,2,1)中的数字1,0,2表示2*3*4这个三维数组的轴1,轴0与轴2,transpose(0,2,1)表示将轴1与轴2交换位置。轴1与轴0交换位置后,三维数组的结构也会从2*3*4变为2*4*3。
这种变换方式比较简单,我们都知道三维数组是由多个二维数组组合而成,轴0不变意味着这些二维数组之间的排列顺序不变(意思就是第一个二维数组下方是第二个二维数组,transpose后这种关系是不会变的,但是每一个二维数组本身的形状可能已经发生改变了)。
理解了上述过程,transpose(0,2,1)实际上就是对组成这个三维数组中的每一个二维数组取个转置而已。
import numpy as np
arr = np.arange(24).reshape((2,3,4))
vc = arr.transpose(0,2,1)
## 结果
print(vc)
[[[ 0 4 8]
[ 1 5 9]
[ 2 6 10]
[ 3 7 11]]
[[12 16 20]
[13 17 21]
[14 18 22]
[15 19 23]]]
2.5 transport(2,1,0)
transport(2,1,0)中的数字1,0,2表示2*3*4这个三维数组的轴1,轴0与轴2。 transport(2,1,0)表示将轴0与轴2交换位置。轴2与轴0交换位置后,三维数组的结构也会从2*3*4变为4*3*2。
本节内容与2.3节的内容基本一致,只不过原来是行的关系不变,现在是列的关系不变而已。故这里不再展开说明,只给出变换结果。
import numpy as np
arr = np.arange(24).reshape((2,3,4))
vc = arr.transpose(2,1,0)
# 结果
print(vc)
[[[ 0 12]
[ 4 16]
[ 8 20]]
[[ 1 13]
[ 5 17]
[ 9 21]]
[[ 2 14]
[ 6 18]
[10 22]]
[[ 3 15]
[ 7 19]
[11 23]]]
2.6 transport(2,0,1)
transport(2,0,1)与前三节均不同,不同点在于没有任何一个轴是不变的。解决方法是将此变换拆分为两个部分,第一个是交换第1轴与第2轴,执行的是transport(0,2,1)变换;第二个是在第一个的变换基础上交换第0轴与第1轴,执行的是transport(1,0,2)变换。
transport(0,2,1)的变换方法可以参见2.4节;将第一个变换得到的结果作为源数组,执行transport(1,0,2)变换,此变换可以参见2.3节。两次变换后便可得到transport(2,0,1)变换的结果。
以下是直接使用transport(2,0,1)变换的结果:
import numpy as np
arr = np.arange(24).reshape((2, 3, 4))
vc = arr.transpose(2, 0, 1)
print(vc)
# 结果
[[[ 0 4 8]
[12 16 20]]
[[ 1 5 9]
[13 17 21]]
[[ 2 6 10]
[14 18 22]]
[[ 3 7 11]
[15 19 23]]]
以下是使用transport(0,2,1)与transport(1,0,2)两次变换后的结果:
import numpy as np
arr = np.arange(24).reshape((2, 3, 4))
vc1 = arr.transpose(0, 2, 1)
vc2 = vc1.transpose(1, 0, 2)
print(vc2)
# 结果
[[[ 0 4 8]
[12 16 20]]
[[ 1 5 9]
[13 17 21]]
[[ 2 6 10]
[14 18 22]]
[[ 3 7 11]
[15 19 23]]]
可以看出两种变换的结果一样。