在数学中,将矩阵的行列互换就称之为转置。那在NumPy数组中也是如此。
NumPy共有三种转置方式T
属性、transpose
方法、swapaxes
方法。
T属性
T属性 它比较常用于二维数组,通过行列互换得到一个新的数组,和数学中的转置是一模一样的。
[图片上传失败...(image-747288-1555413382768)]
通过转置后得到一个行列互换的新的矩阵:
[图片上传失败...(image-d7a1f1-1555413382768)]
In [170]: arr = np.arange(12).reshape(4,3)
In [171]: arr
Out[171]:
array([[ 0, 1, 2],
[ 3, 4, 5],
[ 6, 7, 8],
[ 9, 10, 11]])
In [172]: arr.T
Out[172]:
array([[ 0, 3, 6, 9],
[ 1, 4, 7, 10],
[ 2, 5, 8, 11]])
比较好奇如果在三维数组中通过T属性来转置会发生什么
In [167]: arr = np.arange(24).reshape((3, 2, 4))
In [168]: arr
Out[168]:
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 [169]: arr.T
Out[169]:
array([[[ 0, 8, 16],
[ 4, 12, 20]],
[[ 1, 9, 17],
[ 5, 13, 21]],
[[ 2, 10, 18],
[ 6, 14, 22]],
[[ 3, 11, 19],
[ 7, 15, 23]]])
可以看到三维数组也是可以转置的。值得注意的是它的转置和二维数组的转置有明显的不同。
这里我是这么理解的:
原数组arr
中,0的索引arr[0,0,0]
(接下来简写为[0,0,0]
这种格式)。经过转置后它的索引为[0,0,0]
。
接下来看1的索引[0,0,1]
,经过转置后变成了[1,0,0]
,这样就很好理解了。
再看10的索引[1,0,2]
,经过转置后变成了[2,0,1]
。
到这步相信已经解释的再清楚不过了。
那我们回过头来再看下二维数组
In [171]: arr
Out[171]:
array([[ 0, 1, 2],
[ 3, 4, 5],
[ 6, 7, 8],
[ 9, 10, 11]])
In [172]: arr.T
Out[172]:
array([[ 0, 3, 6, 9],
[ 1, 4, 7, 10],
[ 2, 5, 8, 11]])
原数组arr
中,0的索引arr[0,0]
。经过转置后它的索引为[0,0]
。
接下来看1的索引[0,1]
,经过转置后变成了[1,0]
,这样就很好理解了。
再看10的索引[3,1]
,经过转置后变成了[1,3]
。
所谓的转置其实就是把该元素的索引做了个倒转而已,非常简单。
transpose方法
transpose
和T
的玩法有点差别,它的参数是数组的轴序列,通过改变轴的顺序从而导致数组中各元素索引的改变。
如果对轴不是很了解,可以参考这篇文章
关于NumPy数组的轴
In [196]: arr = np.arange(16).reshape((2, 2, 4))
In [197]: arr # arr 原本的轴序列为(0, 1, 2)
Out[197]:
array([[[ 0, 1, 2, 3],
[ 4, 5, 6, 7]],
[[ 8, 9, 10, 11],
[12, 13, 14, 15]]])
In [199]: arr.transpose((1, 0, 2)) # 参数中,我们把轴的顺序改成了(1, 0, 2)
Out[199]:
array([[[ 0, 1, 2, 3],
[ 8, 9, 10, 11]],
[[ 4, 5, 6, 7],
[12, 13, 14, 15]]])
在这里我们把轴的顺序由原本的(0, 1, 2)
改成了(1, 0, 2)
。也就是把前两位互换了位置,请牢记这句话。
接下来还是按照T
属性的原理:
元素4转置前的索引值为(0, 1, 0)
,现在要把前两位互换下位置变成(1, 0, 0)
, 也就变成了上图中的效果。
元素10转置前的索引值为(1, 0, 2)
,经过互换后变成了 (0, 1, 2)
,如上图。
如果我把三个轴的位置都更改了,那会发生什么?
再看下面这个案例
In [210]: arr.transpose((2,0,1))
Out[210]:
array([[[ 0, 4],
[ 8, 12]],
[[ 1, 5],
[ 9, 13]],
[[ 2, 6],
[10, 14]],
[[ 3, 7],
[11, 15]]])
轴的顺序由原来的(0, 1, 2)
变成了(2, 0, 1)
,三个位置都发生了改变。
我们结合上面的代码来分析下:
元素4从原本的(0, 1, 0)
变成了(0, 0, 1)
元素10从原本的(1, 0, 2)
变成了(2, 1, 0)
这里稍微总结下,transpose
与T
属性最大的区别在于,后者是把各元素的索引序列从左往右全部翻转过来。而前者则可以很灵活的去控制想要转置的元素,在多维数组中优势会更加明显。
swapaxes方法
核心用法与transpose差不多,只是参数发生了变化。
arr.swapaxes(1, 2)
,这段代码的意思是将第一个轴与第二个轴进行交换。也就等同于将轴的顺序由(0, 1, 2)
变成了(0, 2, 1)
。
接下来的索引的专置和transpose
是一样的,这里就略过了。
In [218]: arr.swapaxes(1, 2)
Out[217]:
array([[[ 0, 4],
[ 1, 5],
[ 2, 6],
[ 3, 7]],
[[ 8, 12],
[ 9, 13],
[10, 14],
[11, 15]]])
等同于
In [218]: arr.transpose((0, 2, 1))
Out[218]:
array([[[ 0, 4],
[ 1, 5],
[ 2, 6],
[ 3, 7]],
[[ 8, 12],
[ 9, 13],
[10, 14],
[11, 15]]])
总结
本章学习了数组的转置与轴对换的内容,NumPy共有三种转置方式T
属性、transpose
方法、swapaxes
方法。
T属性: 比较简单粗暴,直接将数组的轴序从左往右翻转且只有这一种方式。例如某个元素在数组中的索引为(1,0,2)
,经过T属性的转置后它的索引将变成(2, 0, 1)
,核心原理与数学的转置相同。
transpose方法 : 它的参数为轴的序列,你可以通过打乱轴的排序来转置数组。例如arr.transpose((0, 2, 1))
,数组的轴序由原来的(0, 1, 2)
变成了(0, 2, 1)
,从而导致元素N
的索引由原来的(a, b, c)
变成了(a, c, b)
。
swapaxes方法: 它的核心原理与transpose相同,唯一的区别是它的参数不是整个轴的序列,而是指定2个轴然后进行互换。例如swapaxes(1, 2)
,这段代码的意思就是轴1与轴2互换,也就是将轴序换成了(0, 2, 1)
,就这个区别。