详解二维,三维数组的 np.transpose 操作

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]]]

可以看出两种变换的结果一样。

  • 21
    点赞
  • 69
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

syphomn

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值