python数据处理(1):numpy---transpose函数

一、前言

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

 
  1. >> import numpy as np

  2. my_arr = np.arrange(1000000)

  3. my_list = list(range(1000000))

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

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

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

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

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

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

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

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

  2. arr

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

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

  6. [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。对以上数组对应的矩阵进行转置:

 
  1. >> arr.T

  2.  
  3. array([[ 0, 5, 10],

  4. [ 1, 6, 11],

  5. [ 2, 7, 12],

  6. [ 3, 8, 13],

  7. [ 4, 9, 14]])

 

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

 
  1. >> arr.swapaxes(1, 0)

  2.  
  3. array([[ 0, 5, 10],

  4. [ 1, 6, 11],

  5. [ 2, 7, 12],

  6. [ 3, 8, 13],

  7. [ 4, 9, 14]])

  8.  
  9.  
  10. >> arr.transpose(1, 0)

  11.  
  12. array([[ 0, 5, 10],

  13. [ 1, 6, 11],

  14. [ 2, 7, 12],

  15. [ 3, 8, 13],

  16. [ 4, 9, 14]])

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

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

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

  2. arr

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

  5. [ 4, 5, 6, 7],

  6. [ 8, 9, 10, 11]],

  7.  
  8. [[12, 13, 14, 15],

  9. [16, 17, 18, 19],

  10. [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。看下图会更直观一点:

 

python数据处理(1):numpy---transpose函数

由上图可以看出,元素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],以此类推,整个数组将变为:

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

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

  5. [12, 13, 14, 15]],

  6.  
  7. [[ 4, 5, 6, 7],

  8. [16, 17, 18, 19]],

  9.  
  10. [[ 8, 9, 10, 11],

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

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

 
  1. >> arr.swapaxes(1, 2)

  2.  
  3.  
  4. array([[[ 0, 4, 8],

  5. [ 1, 5, 9],

  6. [ 2, 6, 10],

  7. [ 3, 7, 11]],

  8.  
  9. [[12, 16, 20],

  10. [13, 17, 21],

  11. [14, 18, 22],

  12. [15, 19, 23]]])

 

相信看到这儿,大家应该对这两个函数的用法更加清楚了吧。

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