術語廣播描述了numpy在算術運算期間如何處理具有不同形狀的陣列。受到某些約束,較小的陣列在較大的陣列上「廣播」,以使它們具有相容的形狀。廣播提供了一種對陣列操作進行向量化的方法,從而使迴圈在c而不是python中發生。這樣做無需複製不必要的資料,通常可以實現高效的演算法實現。但是,在某些情況下,廣播不是乙個好主意,因為廣播會導致記憶體使用效率低下,從而減慢計算速度。
numpy操作通常在逐個陣列的基礎上對陣列進行。在最簡單的情況下,兩個陣列必須具有完全相同的形狀,如以下示例所示:
>>>>>> a = np.array([1.0, 2.0, 3.0])
>>> b = np.array([2.0, 2.0, 2.0])
>>> a * b
array([ 2., 4., 6.])
當陣列的形狀滿足某些約束時,numpy的廣播規則會放寬此約束。在操作中將陣列和標量值組合在一起時,會出現最簡單的廣播示例:
>>>>>> a = np.array([1.0, 2.0, 3.0])
>>> b = 2.0
>>> a * b
array([ 2., 4., 6.])
結果等同於前面的示例,其中b
是乙個陣列。我們可以認為標量在算術運算中b
被拉伸成與形狀相同的陣列a
。中的新元素b
只是原始標量的副本。延伸類推只是概念上的。numpy足夠聰明,可以使用原始標量值而無需實際製作副本,從而使廣播操作盡可能地節省記憶體並提高計算效率。
第二個示例中的**比第乙個示例中的**更有效,因為廣播在乘法過程中會移動較少的記憶體(b
是標量而不是陣列)。
在兩個陣列上進行操作時,numpy逐元素比較其形狀。它從尾隨尺寸開始,一直向前發展。兩種尺寸相容
它們相等,或者
其中之一是1
如果不滿足這些條件, 則會引發異常,表明陣列的形狀不相容。所得陣列的大小是沿輸入的每個軸的大小不為1。valueerror: operands could not be broadcast together
陣列不必具有相同數量的維。例如,如果您有乙個256x256x3
rgb值陣列,並且想用不同的值縮放影象中的每種顏色,則可以將影象乘以一維陣列,並使用3個值。根據廣播規則來排列這些陣列的尾軸的大小,表明它們是相容的:
image (3d array): 256 x 256 x 3
scale (1d array): 3
result (3d array): 256 x 256 x 3
當比較的任一維度為乙個維度時,將使用另乙個維度。換句話說,尺寸為1的尺寸將被拉伸或「複製」以彼此匹配。
在以下示例中,a
和b
陣列都具有長度為1的軸,這些軸在廣播操作期間會擴充套件為更大的大小:
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
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 # trailing dimensions do not match
a (2d array): 2 x 1
b (3d array): 8 x 4 x 3 # second from last dimensions mismatched
實踐中的廣播示例:
>>>>>> 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.]])
廣播提供了一種獲取兩個陣列的外部乘積(或任何其他外部操作)的便捷方法。以下示例顯示了兩個1-d陣列的外部加法運算:
>>>>>> 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
索引運算子將乙個新軸插入a
,使其成為二維4x1
陣列。將4x1
陣列與b
形狀為的組合會(3,)
生成乙個4x3
陣列。
numpy 基礎知識
標準安裝的python中用列表 list 儲存一組值,可以用來當作陣列使用,不過由於列表的元素可以是任何物件,因此列表中所儲存的是物件的指標。這樣為了儲存乙個簡單的 1,2,3 需要有3個指標和三個整數物件。對於數值運算來說這種結構顯然比較浪費記憶體和cpu計算時間。此外python還提供了乙個ar...
NumPy 基礎知識
numpy目錄 numpy 的主要物件是同構多維陣列。它是乙個元素表 通常是數字 所有型別都相同,由非負整數元組索引。在 numpy 中,維度稱為軸。例如,3d 空間中乙個點的座標 1,2,1 只有乙個軸。該軸有 3 個元素,因此我們說它的長度為 3。在下圖中的示例中,陣列有 2 個軸。第乙個軸的長...
OpenGL基礎知識 五
opengl狀態機 在opengl中使用狀態機的機制去儲存opengl當前的狀態。所謂的opengl狀態機也就是一組opengl的狀態集合。有一些狀態可以開啟或關閉,可以通過glenable glenum capability 函式進行開啟,gldisable glenum capability 對...