NumPy 廣播主要應(yīng)用numpy在算術(shù)運(yùn)算期間處理具有不同形狀的數(shù)組。受某些約束的影響,較小的數(shù)組在較大的數(shù)組上“廣播”,以便它們具有兼容的形狀。
NumPy 操作通常在逐個(gè)元素的基礎(chǔ)上在數(shù)組對(duì)上完成。在最簡(jiǎn)單的情況下,兩個(gè)數(shù)組必須具有完全相同的形狀,如下例所示:
>>> import numpy as np >>> a = np.array([1, 2, 3]) >>> b = np.array([2, 2, 2]) >>> a * b array([ 2, 4, 6])
當(dāng)運(yùn)算中的 2 個(gè)數(shù)組的形狀不同時(shí),numpy 將自動(dòng)觸發(fā)廣播機(jī)制。如:
>>> import numpy as np >>> a = np.array([[ 0, 0, 0], [10,10,10], [20,20,20], [30,30,30]]) >>> b = np.array([1,2,3]) >>> print(a + b) [[ 1 2 3] [11 12 13] [21 22 23] [31 32 33]]
下面的圖片展示了數(shù)組 b 如何通過(guò)廣播來(lái)與數(shù)組 a 兼容。
4x3 的二維數(shù)組與長(zhǎng)為 3 的一維數(shù)組相加,等效于把數(shù)組 b 在二維上重復(fù) 4 次再運(yùn)算:
>>> import numpy as np >>> a = np.array([[ 0, 0, 0], [10,10,10], [20,20,20], [30,30,30]]) >>> b = np.array([1,2,3]) >>> bb = np.tile(b, (4, 1)) # 重復(fù) b 的各個(gè)維度 >>> print(a + bb) [[ 1 2 3] [11 12 13] [21 22 23] [31 32 33]]
在兩個(gè)數(shù)組上運(yùn)行時(shí),NumPy會(huì)逐元素地比較它們的形狀。它從尾隨尺寸開始,并向前發(fā)展。兩個(gè)尺寸兼容時(shí)
他們是平等的,或者
其中一個(gè)是1
如果不滿足這些條件,則拋出 ValueError: operands could not be broadcast together 異常,指示數(shù)組具有不兼容的形狀。結(jié)果數(shù)組的大小是沿輸入的每個(gè)軸不是1的大小。
數(shù)組不需要具有相同數(shù)量的維度。例如,如果您有一個(gè)256x256x3RGB值數(shù)組,并且希望將圖像中的每種顏色縮放不同的值,則可以將圖像乘以具有3個(gè)值的一維數(shù)組。根據(jù)廣播規(guī)則排列這些數(shù)組的尾軸的大小,表明它們是兼容的:
Image (3d array): 256 x 256 x 3 Scale (1d array): 3 Result (3d array): 256 x 256 x 3
當(dāng)比較的任何一個(gè)尺寸為1時(shí),使用另一個(gè)尺寸。換句話說(shuō),尺寸為1的尺寸被拉伸或“復(fù)制”以匹配另一個(gè)尺寸。在以下示例中,A和B數(shù)組都具有長(zhǎng)度為1的軸,在廣播操作期間會(huì)擴(kuò)展為更大的大?。?/p>
A (4d array): 8 x 1 x 6 x 1 B (3d array): 7 x 1 x 5 Result (4d array): 8 x 7 x 6 x 5
以下是一些實(shí)例:
A (2d array): 5 x 4 B (1d array): 1 Result (2d array): 5 x 4 A (2d array): 5 x 4 B (1d array): 4 Result (2d array): 5 x 4 A (3d array): 15 x 3 x 5 B (3d array): 15 x 1 x 5 Result (3d array): 15 x 3 x 5 A (3d array): 15 x 3 x 5 B (2d array): 3 x 5 Result (3d array): 15 x 3 x 5 A (3d array): 15 x 3 x 5 B (2d array): 3 x 1 Result (3d array): 15 x 3 x 5
以下是不廣播的形狀示例:
A (1d array): 3 B (1d array): 4 #尾部維度不匹配 A (2d array): 2 x 1 B (3d array): 8 x 4 x 3 #倒數(shù)第二個(gè)維度不匹配
實(shí)踐中廣播的一個(gè)實(shí)例:
>>> import numpy as np >>> x = np.arange(4) >>> xx = x.reshape(4,1) >>> y = np.ones(5) >>> z = np.ones((3,4)) >>> x.shape (4,) >>> y.shape (5,) >>> x + y ValueError: operands could not be broadcast together with shapes (4,) (5,) >>> xx.shape (4, 1) >>> y.shape (5,) >>> (xx + y).shape (4, 5) >>> xx + y array([[ 1., 1., 1., 1., 1.], [ 2., 2., 2., 2., 2.], [ 3., 3., 3., 3., 3.], [ 4., 4., 4., 4., 4.]]) >>> x.shape (4,) >>> z.shape (3, 4) >>> (x + z).shape (3, 4) >>> x + z array([[ 1., 2., 3., 4.], [ 1., 2., 3., 4.], [ 1., 2., 3., 4.]])
廣播提供了一種方便的方式來(lái)獲取兩個(gè)數(shù)組的外積(或任何其他外部操作)。以下示例顯示了兩個(gè)1-d數(shù)組的外積操作:
>>> import numpy as np >>> a = np.array([0.0, 10.0, 20.0, 30.0]) >>> b = np.array([1.0, 2.0, 3.0]) >>> a[:, np.newaxis] + b array([[ 1., 2., 3.], [ 11., 12., 13.], [ 21., 22., 23.], [ 31., 32., 33.]])
這里 newaxis索引操作符插入一個(gè)新軸 a ,使其成為一個(gè)二維 4x1數(shù)組。將 4x1數(shù)組與形狀為 (3,)的 b組合,產(chǎn)生一個(gè) 4x3數(shù)組。