NUMPY 傳播機制

1、 broadcast機制

傳播機制是numpy在算數(shù)計算中處理不同維度數(shù)組的方法。

NumPy 操作通常在逐個元素的基礎上對數(shù)組對進行。 在最簡單的情況下,兩個數(shù)組必須具有完全相同的形狀,如下例所示:

a = np.array([1.0, 2.0, 3.0])
b = np.array([2.0, 2.0, 2.0])
a * b
array([2.,  4.,  6.])

當數(shù)組的形狀滿足某些約束時,NumPy 的廣播規(guī)則會放寬這個約束。 最簡單的廣播示例發(fā)生在同時操作數(shù)組和標量值時:

a = np.array([1.0, 2.0, 3.0])
b = 2.0
a * b
array([2.,  4.,  6.])

這里的結(jié)果前一個示例相同。 想象標量 b 在算術運算期間被拉伸成一個與 a 形狀相同的數(shù)組。 b 中的新元素,如下圖所示,只是原始標量的副本。 拉伸只是概念性的, NumPy 可以使用原始標量值而無需實際制作副本,從而使廣播操作盡可能地提升內(nèi)存和計算效率。

b的“拉伸”
2、廣播規(guī)則

當numpy對兩個數(shù)組進行操作時,他會自右向左比較兩個數(shù)組的維度,若當前維度滿足以下條件,則繼續(xù)比較:

  • 兩個數(shù)組當前維度相同
  • 兩數(shù)組存在一個當前維度為1

否則報錯: ValueError: operands could not be broadcast together

結(jié)果數(shù)組的大小是沿輸入的 每個軸不為 1 的大小。

數(shù)組不需要具有相同的維數(shù)。
例如,如果您有一個 256x256x3 的 RGB 值數(shù)組,并且您希望將圖像中的每種顏色縮放不同的值,則可以將圖像乘以具有 3 個值的一維數(shù)組。 根據(jù)廣播規(guī)則 從尾軸 排列這些數(shù)組的大小,可以看出它們是兼容的:

Image  (3d array): 256 x 256 x 3
Scale  (1d array):             3
Result (3d array): 256 x 256 x 3

當比較的任一維度是1時,使用另一個。 換句話說,尺寸為 1 的維度被拉伸,以匹配另一個維度。

在以下示例中,A 和 B 數(shù)組都有長度為 1 的軸,在廣播操作期間擴展為更大的大?。?/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
3、Broadcastable arrays

如果上述規(guī)則產(chǎn)生有效結(jié)果,則將一組數(shù)組稱為“可廣播”到相同的形狀。
例子:

a = np.array([[ 0.0,  0.0,  0.0],
              [10.0, 10.0, 10.0],
              [20.0, 20.0, 20.0],
              [30.0, 30.0, 30.0]])
b = np.array([1.0, 2.0, 3.0])
a + b
array([[  1.,   2.,   3.],
        [11.,  12.,  13.],
        [21.,  22.,  23.],
        [31.,  32.,  33.]])
image.png
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.]])
image.png
4、 實例 Vector Quantization

VQ 中的基本操作是在一組點(在 VQ 術語中稱為codes )中找到最接近給定點的點,稱為observation。

在二維的場景下:
observation的值描述了要分類的運動員的體重和身高。
codes 代表不同類別的運動員。
找到最近的點需要計算observation和每個codes 之間的距離。
最短距離提供最佳匹配。 在此示例中,codes [0] 是最接近的類別,表明該運動員可能是一名籃球運動員。

from numpy import array, argmin, sqrt, sum
observation = array([111.0, 188.0])
codes = array([[102.0, 203.0],
               [132.0, 193.0],
               [45.0, 155.0],
               [57.0, 173.0]])
diff = codes - observation    # the broadcast happens here
dist = sqrt(sum(diff**2,axis=-1))
argmin(dist)
0

在此示例中,observation 數(shù)組被拉伸以匹配codes 數(shù)組的形狀:

Observation      (1d array):      2
Codes            (2d array):  4 x 2
Diff             (2d array):  4 x 2

通常,將可能從數(shù)據(jù)庫中讀取的大量observation 結(jié)果與一組codes 進行比較。 考慮這種情況:

Observation      (2d array):      10 x 3
Codes            (2d array):       5 x 3
Diff             (3d array):  5 x 10 x 3

三維數(shù)組 diff 是廣播的結(jié)果,而不是計算的必需品。 大型數(shù)據(jù)集將生成計算效率低下的大型中間數(shù)組。 相反,如果使用 Python 循環(huán)圍繞上述二維示例中的代碼單獨計算每個觀察值,則使用更小的數(shù)組。

reference

最后編輯于
?著作權歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

友情鏈接更多精彩內(nèi)容