《利用python进行数据分析》——4.1 NumPy的ndarray一种多维数组对象——数组转置和轴对换——读书笔记

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

我假设这个三维数组在空间中按上图的方式排列,数组里每个数字存放在一个小立方体中

更具体一点,我们的俯视图如下:

clipboard.png

用表格展示这个数组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,多谢大神

发布了15 篇原创文章 · 获赞 11 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/baidu_28660921/article/details/104224790