明白講清楚Numpy的廣播機制到底是怎麼回事(附實例)

一、什麼是Numpy的廣播機制

numpy的廣播機制是在不同shape的ndarray數組進行運算時,將其補足成相同shape再進行運算的機制
比如我們常常需要對一個數據矩陣的每個維度進行零均值化處理,就需要該維度的所有數據減去該維度的均值,代碼如下

import numpy as np
# 模擬一個5*5大小的樣本矩陣,每一行是一個樣本的特徵向量
DATA = np.random.permutation(5*5).reshape((5,5))
DATAMEAN = np.mean(DATA, axis=0)
DATA-DATAMEAN
print(DATA.shape)	# (5,5)
print(DATAMEAN.shape) # (1,5)

雖然這裏DATA和DATAMEAN的shape不一樣,但他們還是能夠相減,這就是numpy的廣播機制起的作用。

二、Numpy廣播機制的規則

前面說到廣播機制是爲了對shape不同的數組(ndarray)進行運算而設計的,shape不同其實分爲兩類:1、維度不同;2、shape的數字不同
前面只對維度相同(DATA和DATAMEAN都是2維),shape不同的數據做了驗證,其實dimesion不同也可以運算,示例如下

b = np.random.permutation(3*3*2).reshape((3,3,2))
print(b.shape)
c = np.array([1,2])
print(b-c)

上面的代碼中,b是3維,shape是(3,3,2));c是1維,shape是(2,),也能正常相減而不報錯。
根據我的總結,Numpy的廣播機制在遇到shape不同的數組相運算時,按照以下步驟進行廣播:
1. 檢查維度是否相同,如果維度不同,在現有維度前補足維度
例如前面提到的c,其維度是1維,shape是(2,),補足後維度是3維,shape是(1,1,2),c從[1,2]變成了[[[1],[2]]]。這裏注意補足的維度都是在前面補足的,就是說shape變成(1,1,2),而不會變成(2,1,1)
2.滿足維度相同後,在維度長度爲1的軸上對其他軸的數據進行復制
還是使用前面提到的c,在c的shape變成(1,1,2)之後,複製第3個軸的數據,使得廣播完成後的afterc[x, y, i] = beforec[1, 1, i],其中x,y是任意滿足條件的索引,i是未進行擴展的軸。

三、實例驗證

前面已經有了兩個代碼實例,這裏再放一個廣播之後仍然不能計算的實例,大家可以照着前面的步驟,看看爲什麼會報錯:

b = np.random.permutation(3*3*2).reshape((3,2,3))
print(b.shape)
c = np.array([1,2])
print(b-c)

這個例子和前面的例子類似,但我只改了b的shape。
可以看到,b的shape爲(3,2,3),而c的shape爲(2,),不管怎麼添加維度,他們的最後一維始終不一樣,所以不能補足成相同的shape。因此會報錯,由此也可以看出,在維度不一樣時,兩個計算的數組的尾部維度必須一樣,不然無法運算
下面還有一個例子:

b = np.random.permutation(3*3*2).reshape((3,2,3))
print(b.shape)
c = np.array([1,2,0])
print(b-c[:,None,None])

這個例子和前面的例子又有一點點不同,這裏使用c[:, None, None]強行將c的shape變成了(3,1,1),這時b的shape是(3,2,3),廣播機制會將c廣播爲shape(3,2,3),廣播後的矩陣假設爲afterc,滿足afterc[i, x, y] = c[i, 1,1]。
其實不止numpy這樣,MATLAB矩陣和pytorch張量都存在類似機制,其方式也相同,不過我沒有進行實驗比較,就不多說了。
至此廣播機制就沒什麼可以說的了,前面都是根據我的實驗總結得到的,如果有錯誤,請指出交流!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章