NumPy 數學操作和廣播
Jinku Hu
2023年1月30日
我們會在接下來的幾節中介紹 NumPy 的計算,包括簡單的四則運算以及矩陣運算,首先我們從最常見的四則運算開始。
NumPy 四則運算
加減乘除四則運算,在 NumPy 中是最基本的運算,跟我們平常普通數字之間的運算,在表現形式上也很類似。
import numpy as np
arrayA = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]])
arrayB = arrayA.T
# array([[1, 2, 3],
# [4, 5, 6],
# [7, 8, 9]])
arrayB = arrayA.T
# array([[1, 4, 7],
# [2, 5, 8],
# [3, 6, 9]])
arrayA + arrayB
# array([[ 2, 6, 10],
# [ 6, 10, 14],
# [10, 14, 18]])
arrayA - arrayB
# array([[ 0, -2, -4],
# [ 2, 0, -2],
# [ 4, 2, 0]])
arrayA * arrayB
# array([[ 1, 8, 21],
# [ 8, 25, 48],
# [21, 48, 81]])
arrayA / arrayB
# array([[1. , 0.5 , 0.42857143],
# [2. , 1. , 0.75 ],
# [2.33333333, 1.33333333, 1. ]])
這裡需要注意的是矩陣乘法*
運算,是將兩個矩陣相同位置上的元素相乘得到結果矩陣上該位置上的元素,而不是矩陣運算上的內積,內積也就是點積,是通過 np.dot()
來計算的。
np.dot(arrayA, arrayB)
# array([[ 14, 32, 50],
# [ 32, 77, 122],
# [ 50, 122, 194]])
NumPy 廣播
理論上,矩陣運算的兩個矩陣需要具有相同的形狀,也就是兩矩陣的行列數相等。但在 NumPy 中,引入了廣播(broadcasting)的概念,用於當兩矩陣的形狀不等時,假如有可能的話,會自動補齊資料,從而來實現運算。我們還是看下面的一個例子,
import numpy as np
arrayA = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]])
arrayA + 1
# array([[ 2, 3, 4],
# [ 5, 6, 7],
# [ 8, 9, 10]])
這裡 1
跟矩陣當中的所有元素相加,換句話說 1
從一個 (1, 1)
形狀的矩陣,廣播到了 (3, 3)
形狀,資料用元素 1
填充。在實際 NumPy 中,arrayA + 1
時這樣計算的
arrayA + np.array([[1, 1, 1], [1, 1, 1], [1, 1, 1]])
NumPy 廣播還可以有下面的用法
兩矩陣具有某一相同的維度,而另外一維其中一矩陣長度為 1
還是先來看具體例子,
arrayC = np.array([10, 11, 12])
arrayA + arrayC
# array([[11, 13, 15],
# [14, 16, 18],
# [17, 19, 21]])
矩陣 arrayA
的形狀是 (3, 3)
,矩陣 arrayC
的形狀是 (3, )
,或者你可以把它看成是 (3, 1)
形狀的,也就是它只有一行。它們滿足有某一相同的維度(列數相同),另外一維其中某一矩陣長度為 1(矩陣 arrayC
的行數為 1),那麼 NumPy 就會把 arrayC
上的唯一一行資料廣播到三行,跟 arrayA
進行匹配。
同理,下面的例子是行數相同,而一矩陣的列數為 1 的情況。
arrayD = np.array([[10], [11], [12]])
# array([[10],
# [11],
# [12]])
arrayA + arrayD
# array([[11, 12, 13],
# [15, 16, 17],
# [19, 20, 21]])