講完了數(shù)組對象的基本知識,我們今天看看如何變化一個數(shù)組的結(jié)構(gòu),也就是轉(zhuǎn)置操作。
轉(zhuǎn)置,就是在數(shù)組維度不變的情況下,使數(shù)組結(jié)構(gòu)發(fā)生變化的過程。
轉(zhuǎn)置可能是體、行、列的數(shù)目發(fā)生變化,也可能是元素的排列順序發(fā)生變化。但一個數(shù)組的轉(zhuǎn)置,其維度永遠(yuǎn)不變。
轉(zhuǎn)置有點(diǎn)類似玩魔方。設(shè)想一下你也可以將魔方各種顛倒、行變列、列變行,也可以扭轉(zhuǎn)魔方把小塊打散。但魔方永遠(yuǎn)是一個立方體(用錘子不算)。
轉(zhuǎn)置包括以下操作方法:
- np.transpose()方法:將數(shù)組的shape進(jìn)行對調(diào),有參數(shù)。
- object.T方法(沒有括號):將行列對調(diào)。
- np.swapaxes()方法:調(diào)換shape的任意兩個值,有參數(shù)。
- np.rollaxis()方法:將指定的shape值滾到指定的位置,有參數(shù)。
np.transpose()方法:
將一個數(shù)組的維度,按指定要求對調(diào)。共有兩個參數(shù):
- a:指定的數(shù)組;
- axes:指定的維度順序,接收一個元組,該元組像索引一樣,對應(yīng)著數(shù)組shape(c,b,a)的參數(shù)。
像這樣:

import numpy as np
arr = np.arange(24).reshape((2,3,4)) # 2塊 3行 4列
print('原arr數(shù)組:\n',arr)
arr1 = np.transpose(arr, axes=(1,2,0)) # 3塊 4行 2列
print('轉(zhuǎn)置后的arr1數(shù)組:\n',arr1)
# 運(yùn)行結(jié)果:
原arr數(shù)組:
[[[ 0 1 2 3]
[ 4 5 6 7]
[ 8 9 10 11]]
[[12 13 14 15]
[16 17 18 19]
[20 21 22 23]]]
轉(zhuǎn)置后的arr1數(shù)組:
[[[ 0 12]
[ 1 13]
[ 2 14]
[ 3 15]]
[[ 4 16]
[ 5 17]
[ 6 18]
[ 7 19]]
[[ 8 20]
[ 9 21]
[10 22]
[11 23]]]
發(fā)現(xiàn)了嗎?
既然理解了axes=(0,1,2)和shape參數(shù)(叫“軸”)呈索引對應(yīng)關(guān)系,也就懂了元素是如何被調(diào)換的。是的,每個元素都有一個index坐標(biāo)系(如上例中的元素“0”是[0, 0, 0],元素“14”是[1, 0, 2]),逐一對每個元素坐標(biāo)執(zhí)行axes的調(diào)換規(guī)則就是了。
最后說一句,transpose()方法不寫axes參數(shù),代表直接行列對倒(“軸”對倒),如(2,4)到(4,2),(2,5,3)到(3,5,2)等等。
object.T方法(沒有括號):
這個操作和transpose()方法不帶參時別無二致,不多講了。
swapaxes()方法:
該方法用于交換數(shù)組的任意兩個軸。共有三個參數(shù):
- a:指定的數(shù)組;
- axis1:要對調(diào)的一個軸;
- axis2:要對調(diào)的另一個軸。
import numpy as np
arr = np.arange(24).reshape((2,3,4)) # 2塊 3行 4列
print('原arr數(shù)組:\n',arr)
print('原arr數(shù)組的shape:',arr.shape)
arr1 = np.swapaxes(arr, axis1=1, axis2=2) # arr的1軸(行)和2軸(列)對調(diào)。也可寫成(arr,2,1)是一個意思
print('對調(diào)任意兩個軸后的arr1數(shù)組:\n',arr1)
print('arr1的shape:',arr1.shape)
# 運(yùn)行結(jié)果:
原arr數(shù)組:
[[[ 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數(shù)組的shape: (2, 3, 4)
對調(diào)任意兩個軸后的arr1數(shù)組:
[[[ 0 4 8]
[ 1 5 9]
[ 2 6 10]
[ 3 7 11]]
[[12 16 20]
[13 17 21]
[14 18 22]
[15 19 23]]]
arr1的shape: (2, 4, 3)
rollaxis()方法:
將指定的shape值滾到指定的位置。注意rolaxis是滾,不是調(diào)。

參數(shù)也有三個:
- a:指定的數(shù)組;
- axis:指定要滾動的軸;
- start:滾到第幾位。不寫默認(rèn)start=0,即讓軸移動到第一位。
import numpy as np
arr = np.arange(120).reshape((3,5,2,4)) # 2塊 3行 4列
arr1 = np.rollaxis(arr, axis=0, start=4) # shape()的0軸滾到第4個
arr2 = np.rollaxis(arr, axis=2, start=1) # shape()的2軸滾到第2個
arr3 = np.rollaxis(arr, axis=3, start=4) # shape()的3軸滾到第4個
arr4 = np.rollaxis(arr, axis=3, start=2) # shape()的3軸滾到第3個
arr5 = np.rollaxis(arr, axis=0, start=0) # shape()的0軸滾到第1個
print('原arr數(shù)組的shape:',arr.shape)
print('arr1的shape:',arr1.shape)
print('arr2的shape:',arr2.shape)
print('arr3的shape:',arr3.shape)
print('arr4的shape:',arr4.shape)
print('arr5的shape:',arr5.shape)
# 運(yùn)行結(jié)果:
原arr數(shù)組的shape: (3, 5, 2, 4)
arr1的shape: (5, 2, 4, 3)
arr2的shape: (3, 2, 5, 4)
arr3的shape: (3, 5, 2, 4)
arr4的shape: (3, 5, 4, 2)
arr5的shape: (3, 5, 2, 4)
以上是數(shù)組轉(zhuǎn)置的所有內(nèi)容。其實(shí)四個方法有很多共通之處,底層都是調(diào)動軸索引到指定位置。
我們拿一個小案例,用四種方法實(shí)現(xiàn)對一個二維數(shù)組的T轉(zhuǎn)置(行列互倒)。
import numpy as np
arr = np.arange(12).reshape(3, 4)
arr1 = np.transpose(a=arr, axes=(1,0)) # 將0軸和1軸重新排序
arr2 = np.swapaxes(a=arr, axis1=0, axis2=1) # 將0軸和一軸對調(diào)
arr3 = arr.T # T轉(zhuǎn)置
arr4 = np.rollaxis(a=arr, axis=1, start=0) # 將1軸提到最前面
print('arr數(shù)組的shape:', arr.shape)
print('arr1數(shù)組的shape:', arr1.shape)
print('arr2數(shù)組的shape:', arr2.shape)
print('arr3數(shù)組的shape:', arr3.shape)
print('arr4數(shù)組的shape:', arr4.shape)
# 運(yùn)行結(jié)果:
arr數(shù)組的shape: (3, 4)
arr1數(shù)組的shape: (4, 3)
arr2數(shù)組的shape: (4, 3)
arr3數(shù)組的shape: (4, 3)
arr4數(shù)組的shape: (4, 3)
“軸”,是操作array對象非常重要的概念。讓我們再總結(jié)下何為“軸”:
軸,基于數(shù)組的shape而存在。
當(dāng)shape有1個,即(a,):
此時a是0軸;代表array對象的最小元素 --- 列。當(dāng)shape為2個,即(b,a):
此時b是0軸,代表array對象的 --- 行;
此時a是1軸,代表array對象的最小元素 --- 列。當(dāng)shape為3個,即(c,b,a):
此時c是0軸,代表array對象的 --- 塊;
此時b是1軸,代表array對象的 --- 行;
此時a是2軸,代表array對象的最小元素 --- 列。當(dāng)shape為4個,即(d,c,b,a):
此時d是0軸,代表array對象的 --- 大塊(土話別介意 =。=);
此時c是1軸,代表array對象的 --- 小塊;
此時b是2軸,代表array對象的 --- 行;
此時a是3軸,代表array對象的最小元素 --- 列。
有邏輯的地方在于,在shape(2,3,4)中,你可以把軸理解為shape元素的索引,通過索引定位到shape元素,并實(shí)現(xiàn)元素間的各種對倒和互換;
而在一個可視化的數(shù)組中,比如print(array)時,可以把軸理解為數(shù)組的顆粒度遞增,就像上面的shape(d,c,b,a),0軸代表大塊,1軸代表小塊,2軸代表行,3軸代表列。而shape(a,),0軸代表列,因?yàn)榱幸呀?jīng)是最小的分割單位了。
更新一下numpy系列的學(xué)習(xí)進(jìn)度:
后面會再講一下numpy的數(shù)組拼接和分割,希望用一篇搞定。而后有關(guān)數(shù)組的常規(guī)操作就講完了,到此你也對numpy的玩法有了相當(dāng)全面的掌握。再往后就是各種數(shù)學(xué)函數(shù)的調(diào)用,用來實(shí)現(xiàn)特定的計(jì)算。沒有太多燒腦的部分,甚至需要時再百度也來得及。