2.3.2 数组翻转变换**
转置变换-transpose函数
进行矩阵运算时,经常要用数组转置,比如计算矩阵内积X^T X,这时就需要利用数组转置。二维数组的转置就是行变成列,列变成行。
函数定义:numpy.transpose(arr, axes)
- arr:要操作的数组
- axes:整数元组,对应维度,通常所有维度都会对换。
In [32]:
arr3_2_1 = np.arange(12).reshape(3,4) arr3_2_1
Out[32]:
array([[ 0, 1, 2, 3], [ 4, 5, 6, 7], [ 8, 9, 10, 11]])
In [33]:
np.transpose(arr3_2_1) #同arr3_2_1.transpose()
Out[33]:
array([[ 0, 4, 8], [ 1, 5, 9], [ 2, 6, 10], [ 3, 7, 11]])
- numpy.transpose类似numpy.ndarray.T,T主要适用于一、二维数组,高维数组置换行列一般用transpose
In [34]:
arr3_2_1.T
Out[34]:
array([[ 0, 4, 8], [ 1, 5, 9], [ 2, 6, 10], [ 3, 7, 11]])
- 对于高维数组,transpose需要用到一个由轴编号组成的元组,才能进行转置。
In [35]:
arr3_2_2 = arr3_2_1.reshape(2,2,3) arr3_2_2
Out[35]:
array([[[ 0, 1, 2], [ 3, 4, 5]], [[ 6, 7, 8], [ 9, 10, 11]]])
In [36]:
for i in [0,1]: for j in [0,1]: for k in [0,1,2]: print(arr3_2_2[i,j,k])
0 1 2 3 4 5 6 7 8 9 10 11
In [37]:
arr3_2_2
Out[37]:
array([[[ 0, 1, 2], [ 3, 4, 5]], [[ 6, 7, 8], [ 9, 10, 11]]])
In [38]:
arr3_2_2.transpose(1,0,2)
Out[38]:
array([[[ 0, 1, 2], [ 6, 7, 8]], [[ 3, 4, 5], [ 9, 10, 11]]])
该变换是轴0和轴1对换,而轴0和轴1都只有两组元素,所以原先的索引[0,0,:]和索引[1,1,:]不用改变,而只是索引[0,1,:]与索引[1,0,:]对调。
In [39]:
arr3_2_2[0,1,:]
Out[39]:
array([3, 4, 5])
In [40]:
arr3_2_2[0,0,:]
Out[40]:
array([0, 1, 2])
In [41]:
arr3_2_2[1,1,:]
Out[41]:
array([ 9, 10, 11])
In [42]:
arr3_2_2[1,0,:]
Out[42]:
array([6, 7, 8])
不好理解的话就展平再reshape,展平时前两个轴向迭代顺序对换。
In [43]:
list0 = [] for j in [0,1]: for i in [0,1]: #前两个轴向迭代的顺序对换 for k in [0,1,2]: print(arr3_2_2[i,j,k])#i仍然表示轴0取值,j表示轴1,k表示轴2 list0.append(arr3_2_2[i,j,k])
0 1 2 6 7 8 3 4 5 9 10 11
In [44]:
list0
Out[44]:
[0, 1, 2, 6, 7, 8, 3, 4, 5, 9, 10, 11]
或者用列表生成式写成如下展平,结果一样。
In [45]:
list1 = [arr3_2_2[i,j,k] for j in [0,1] for i in [0,1] for k in [0,1,2]] list1
Out[45]:
[0, 1, 2, 6, 7, 8, 3, 4, 5, 9, 10, 11]
再创建NumPy数组并重塑成(2,2,3)形状:
In [46]:
arr3_2_3 = np.array(list0).reshape(2,2,3) arr3_2_3
Out[46]:
array([[[ 0, 1, 2], [ 6, 7, 8]], [[ 3, 4, 5], [ 9, 10, 11]]])
In [47]:
arr3_2_2.transpose(2,0,1)
Out[47]:
array([[[ 0, 3], [ 6, 9]], [[ 1, 4], [ 7, 10]], [[ 2, 5], [ 8, 11]]])
这个结果难以理解,通过迭代展平再重塑就很好理解,上述转置就是在展平迭代过程中,将原数组的轴2放到轴0,轴0放到轴1,轴1放到轴2:
In [48]:
list2 = [] for k in [0,1,2]: for i in [0,1]: for j in [0,1]: print(arr3_2_2[i,j,k]) list2.append(arr3_2_2[i,j,k])
0 3 6 9 1 4 7 10 2 5 8 11
In [49]:
list2
Out[49]:
[0, 3, 6, 9, 1, 4, 7, 10, 2, 5, 8, 11]
In [50]:
arr3_2_4 = np.array(list2).reshape(3,2,2) #重塑成(3,2,2),即(原先的轴2形状,轴0形状和轴1形状) arr3_2_4
Out[50]:
array([[[ 0, 3], [ 6, 9]], [[ 1, 4], [ 7, 10]], [[ 2, 5], [ 8, 11]]])
另外,若只是置换某个维度的索引顺序,可以直接在数组上改变该维度的索引,这种操作在花式索引部分已经讲过。
交换数组np.arange(12).reshape(4,3)中的第0列和第1列:
In [51]:
arr3_2_5 = np.arange(12).reshape(4,3) arr3_2_5
Out[51]:
array([[ 0, 1, 2], [ 3, 4, 5], [ 6, 7, 8], [ 9, 10, 11]])
In [52]:
arr3_2_6 = arr3_2_5[:,[1,0,2]] arr3_2_6
Out[52]:
array([[ 1, 0, 2], [ 4, 3, 5], [ 7, 6, 8], [10, 9, 11]])
In [53]:
arr3_2_5
Out[53]:
array([[ 0, 1, 2], [ 3, 4, 5], [ 6, 7, 8], [ 9, 10, 11]])
交换数组np.arange(12).reshape(4,3)中的第0行和第1行:
In [54]:
arr3_2_7 = arr3_2_5[[1,0,2,3],:] arr3_2_7
Out[54]:
array([[ 3, 4, 5], [ 0, 1, 2], [ 6, 7, 8], [ 9, 10, 11]])
2.3.3 数组堆叠**
数组堆叠就是把两个数组按照某个轴向(维度)拼接在一起,通常堆叠函数有如下几个:
- 使用hstack函数实现数组横向组合:np.hstack((arr1,arr2))
- 使用vstack函数实现数组纵向组合:np.vstack((arr1,arr2))
- 使用concatenate函数实现数组横向组合:np.concatenate((arr1,arr2),axis = 1))
- 使用concatenate函数实现数组纵向组合:np.concatenate((arr1,arr2),axis = 0))
对于多维数组的堆叠,vstack只能按轴0,hstack只能按轴1,其他维度的堆叠则可以通过concatenate函数指定轴向进行。堆叠的条件是两个数组除了堆叠的轴向上的元素数可以不同外,其他轴向须具有相同的形状。
注意:上述函数传入的堆叠数组需要组成元组形式。
vstack(tup):垂直堆叠数组
除了轴0之外,数组的其他维度必须具有相同的形状。
一维数组必须具有相同的长度。
返回堆叠的数组
通过堆叠形成的数组将至少为二维的。
hstack(tup)
除了轴1之外,数组的其他维度必须具有相同的形状。
返回:通过堆叠形成的数组。
如下创建的4个三维数组:
In [55]:
import numpy as np arr3_3_1 = np.arange(24).reshape(2,3,4) arr3_3_1
Out[55]:
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 [56]:
arr3_3_2 = np.arange(30,42).reshape(1,3,4) arr3_3_2
Out[56]:
array([[[30, 31, 32, 33], [34, 35, 36, 37], [38, 39, 40, 41]]])
In [57]:
arr3_3_3 = np.arange(50,66).reshape(2,2,4) arr3_3_3
Out[57]:
array([[[50, 51, 52, 53], [54, 55, 56, 57]], [[58, 59, 60, 61], [62, 63, 64, 65]]])
In [58]:
arr3_3_4 = np.arange(70,82).reshape(2,3,2) arr3_3_4
Out[58]:
array([[[70, 71], [72, 73], [74, 75]], [[76, 77], [78, 79], [80, 81]]])
根据hstack和vstack特性:
- 我们可