標籤:
多維陣列下標
多維陣列的下標是用元組來實現每一個維度,如果元組的長度比維度大則會出錯,如果小,則預設元組後面補 : 表示全部訪問;
如果一個下標不是元組,則先轉換為元組,在轉換過程中,列表和數組的轉換有所不同。
一個列表會被轉換成各個元素組成的元組,然後進行訪問(此時如果不全為整數的話,則不會共用儲存地區,因為無法通過改變步長來保持儲存結構不變);如:lidx=[[0],[1],[2]];如果用lidx來訪問一個數組,則會被轉換成:([0],[1],[2]),即訪問(0,1,2)上的元素;
一個數組會進行補 : 操作轉成長度一致的元組,如三維數組a:
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, 24],
[25, 26, 27, 28, 29],
[30, 31, 32, 33, 34],
[35, 36, 37, 38, 39]],
[[40, 41, 42, 43, 44],
[45, 46, 47, 48, 49],
[50, 51, 52, 53, 54],
[55, 56, 57, 58, 59]]])
如果使用一個數組來訪問:aidx=np.array([[0],[1],[2]]):
array([[0],
[1],
[2]])
則會被補全為:(aidx,:,:),訪問結果為:
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, 24],
[25, 26, 27, 28, 29],
[30, 31, 32, 33, 34],
[35, 36, 37, 38, 39]]],
[[[40, 41, 42, 43, 44],
[45, 46, 47, 48, 49],
[50, 51, 52, 53, 54],
[55, 56, 57, 58, 59]]]])
結果的形狀是訪問下標數組的形狀和原數組形狀的組合:原數組形狀為(3,4,5),下標數組形狀為:(3,1);訪問得到的數組形狀為:(3,1,4,5);訪問數組在0軸位置替代原數組形狀;
相當於a(aidx,:,:),如果訪問:a(:,aidx,:),則訪問的形狀應該為(3,3,1,5),即在1軸位置替代原數組形狀;
廣播
再複習一下廣播,詳細規則見隨筆:http://www.cnblogs.com/lyon2014/p/4696989.html
如上例的a數組,a.shape = (3,4,5),如果使用數組來訪問,則會在對應的位置替代原數組的形狀,如果下標中有多個數組,且形狀不一致,則會進行廣播,如:
i0 = np.array([[1,2,1],[0,1,0]]) ?, i0.shape=(2,3)
i1 = np.array([[[0]],[[1]]]), i1.shape=(2,1,1)
i2 = np.array([[[2,3,2]]]), i2.shape=(1,1,3)
按照廣播的規則,i0的維數比最大維數3少,進行補1操作得到新的形狀為:(1,2,3),再比較各個軸的長度:
1 2 3
2 1 1
1 1 3?
--------
2 2 3
最後結果的形狀為(2,2,3),且滿足第三條規則,可以進行計算;廣播後的三個數組(記為:ind0,ind1,ind2)為:
ind0:
array([[[1, 2, 1],
[0, 1, 0]],
[[1, 2, 1],
[0, 1, 0]]])
ind1:
array([[[0, 0, 0],
[0, 0, 0]],
[[1, 1, 1],
[1, 1, 1]]])
ind2:
array([[[2, 3, 2],
[2, 3, 2]],
[[2, 3, 2],
[2, 3, 2]]])
此時,使用廣播後的三個數組訪問數組a(i0,i1,i2),得到的數組形狀應該只與下標數組有關,即廣播後的數組形狀:(2,2,3);
如果a使用其中的兩個數組訪問:a(:,i0,i1),由於i0和i1廣播後的形狀為 (2,2,3),在1、2軸替換a數組的形狀,最後得到的形狀為:(3,2,2,3);
如果a使用其中兩個數組訪問,並且兩個數組不連續:a(i0,:,i1),則第二軸會作為最後一維,即形狀應該為廣播後形狀加上切片軸的形狀:(2,2,3,4)
布爾數組作為下標
布爾數組作為下標時,相當於用nonzero()處理後的元組作為下標;
如:b2 = np.array([[True,False,True],[True,False,False]]) 作為下標,相當於:
np.nonzero(b2) =?(array([0, 0, 1]), array([0, 2, 0]))
a[b2] = a[np.nonzero(b2)] = a[ array([0, 0, 1]), array([0, 2, 0]), :?], 前兩軸由於作為元組訪問,最後得到的形狀為(3,),最後訪問到的形狀為:(3,5)
python科學計算_numpy_廣播與下標