NJU1healer的个人博客分享 http://blog.sciencenet.cn/u/NJU1healer

博文

[转载]Python numpy模块:transpose以及swapaxes函数(矩阵理解及性能)

已有 477 次阅读 2020-11-13 20:18 |个人分类:Python|系统分类:科研笔记|文章来源:转载

一、前言

众所周知,python的numpy模块在数据分析中占有重要的地位,因其所定义的 ndarray(n-dimensional array,多维数组)对象比之python基本类库所定义的 list 对象而言,具有更高的灵活性和更广的适用范围。更重要的是,由于numpy模块是用C语言编写的,因此计算机在处理 ndarray 对象时的速度要远快于 list 对象。看一个例子:

>>  import numpy as np

    my_arr = np.arrange(1000000)

    my_list = list(range(1000000))

 

>>  %time for _ in range(10): my_arr2 = my_arr * 2

  

    CPU times: user 17.7 ms, sys: 12.5 ms, total: 30.1 ms Wall time: 29.9 ms

 

 

>>  %time for _ in range(10): my_list2 = [x * 2 for x in my_list]

   

    CPU times: user 525 ms, sys: 105 ms, total: 630 ms Wall time: 629 ms

可以明显地看出,当数字大小达到百万数量级时,使用 ndarray 对象的运算时间比使用 list 对象运算时间有明显的减少。而实际的数据分析中用到的数据只会更大,这时使用 ndarray 显然是一个更为明智的选择。

二、numpy中transpose函数及swapaxes函数的用法

首先从二维数组开始,构造一个数组如下:

>> arr = np.arange(15).reshape((3, 5))

   arr

     

   array([[ 0,  1,  2,  3,  4],

          [ 5,  6,  7,  8,  9],

          [10, 11, 12, 13, 14]])

reshape的作用是生成一个3X5的二维数组arr。我们可以把此处的arr看作一个3X5阶的矩阵,学过线性代数的朋友应该知道,此时矩阵元素0可表示为a11,7可表示为a23,13可表示为a34。而对应的数组中,0可表示为arr[0][0],7可表示为arr[1][2],13可表示为arr[2][3]。

我们可以用arr[m][n](m=0,1,2;n=0,1,2,3)来表示此数组中的元素。此时我们称此二位数组arr有两条轴,分别表示为0和1,其中m对应的轴为0,n对应的轴为1。对以上数组对应的矩阵进行转置:

>> arr.T

   

   array([[ 0,  5, 10],

          [ 1,  6, 11],          

          [ 2,  7, 12],            

          [ 3,  8, 13],

          [ 4,  9, 14]])

相信学过线性代数的朋友很好理解,此矩阵转置操作等价于将轴0和1交换,对应于numpy模块中定义的的transpose函数以及swapaxes函数可表示为:

>> arr.swapaxes(1, 0)

 

   array([[ 0,  5, 10],

          [ 1,  6, 11],

          [ 2,  7, 12],

          [ 3,  8, 13],

          [ 4,  9, 14]])

 

 

>> arr.transpose(1, 0)

   

   array([[ 0,  5, 10],

          [ 1,  6, 11],

          [ 2,  7, 12],

          [ 3,  8, 13],

          [ 4,  9, 14]])

可以看出,以上变换是等价的,均是一种“轴变换”。

二维数组相对容易理解,三维数组相对复杂一点,但基本原理不变,不过是在二位数组的基础上增加了一条轴。构造以下三维数组:

>> arr = np.arange(24).reshape((2, 3, 4))

   arr

 

   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[x][y][z](x=0,1; y=0,1,2; z=0,1,2,3)来表示,此时x对应轴0,y对应轴1,z对应轴2。看下图会更直观一点:

image.png

由上图可以看出,元素0可表示为arr[0][0][0],元素6可表示为arr[0][1][2],元素12可表示为arr[1][0][0],元素18可表示为arr[1][1][2],元素22可表示为arr[1][2][2]。那么此时若使用函数transpose(1,0,2),即代表将轴0和1对换,轴2不变,亦即将arr[x][y][z]中x和y位置互换,即元素12变为arr[0][1][0],元素22变为arr[1][2][2],以此类推,整个数组将变为:

>> arr.transpose((1, 0, 2)

 

 

   array([[[ 0,  1,  2,  3],

           [12, 13, 14, 15]],

 

          [[ 4,  5,  6,  7],

           [16, 17, 18, 19]],

 

          [[ 8,  9, 10, 11],

           [20, 21, 22, 23]]])

同理,swapaxes(1,2)即表示将轴1和2位置互换,轴0不变:

>> arr.swapaxes(1, 2)

 

 

   array([[[ 0,  4,  8],

           [ 1,  5,  9],

           [ 2,  6, 10],

           [ 3,  7, 11]],

 

          [[12, 16, 20],

           [13, 17, 21],

           [14, 18, 22],

           [15, 19, 23]]])

此问题的关键在于搞清楚轴与元素位置的对应关系,以及在进行轴变换时,对应的元素位置会发生怎么样的改变,进而会导致整个数组的形状发生怎样的改变。

【参考】

https://blog.csdn.net/lothakim/article/details/79494782

点滴分享,福泽你我!Add oil!



http://wap.sciencenet.cn/blog-3428464-1258265.html

上一篇:import torchnet as tnt
下一篇:[Pytorch函数] .masked_fill_()与Numpy数组中None的作用

0

该博文允许注册用户评论 请点击登录 评论 (0 个评论)

数据加载中...
扫一扫,分享此博文

Archiver|手机版|科学网 ( 京ICP备07017567号-12 )

GMT+8, 2021-1-16 17:44

Powered by ScienceNet.cn

Copyright © 2007- 中国科学报社

返回顶部