NumPy基礎知識(五)

2021-10-17 18:49:01 字數 3984 閱讀 3786

術語廣播描述了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

陣列不必具有相同數量的維。例如,如果您有乙個256x256x3rgb值陣列,並且想用不同的值縮放影象中的每種顏色,則可以將影象乘以一維陣列,並使用3個值。根據廣播規則來排列這些陣列的尾軸的大小,表明它們是相容的:

image  (3d array): 256 x 256 x 3

scale (1d array): 3

result (3d array): 256 x 256 x 3

當比較的任一維度為乙個維度時,將使用另乙個維度。換句話說,尺寸為1的尺寸將被拉伸或「複製」以彼此匹配。

在以下示例中,ab陣列都具有長度為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 對...