6.8. 運算子

numpyndarray 上執行的第一類數學運算是標準的 Python 運算子。算術、比較與位元運算子全都以逐元素方式運作 -- 每個運算子都在單一的函式庫呼叫中,從頭到尾走過陣列(或兩個陣列)一次,比起對等的 Python for 迴圈要快得多。

6.8.1. 算術運算

+-*///%** 全都可在兩個形狀相容的陣列之間運作,或在一個陣列與一個純量之間運作:

a = np.array([1, 2, 3, 4], dtype=np.float)
b = np.array([10, 20, 30, 40], dtype=np.float)

print(a + b)        # array([11.0, 22.0, 33.0, 44.0])
print(a * 2)        # array([2.0, 4.0, 6.0, 8.0])
print(b - a)        # array([9.0, 18.0, 27.0, 36.0])
print(b / a)        # array([10.0, 10.0, 10.0, 10.0])

結果的 dtype 遵循 Dtype 資料型別 中所述的向上轉型(upcasting)規則。整數陣列在溢位時會繞回(wrap);當這有影響時,請在運算前先轉型為更寬的 dtype。

矩陣乘法運算子 @ 並未實作。請使用 dot() 進行矩陣/向量乘積。

6.8.1.1. 就地(in-place)形式

每個算術運算子都有一個就地形式 -- +=-=*=/=%=**=。就地形式會直接寫入現有的緩衝區,而非配置一個暫存區:

b = b + 1            # allocates a temporary the size of b
b += 1               # no temporary

在微控制器上,對於任何熱迴圈而言,第二種形式基本上是必須採用的。

6.8.2. 位元運算

位元運算子 &|^ 會在整數陣列上逐元素運作。若套用於 floatcomplex 陣列,則會引發 TypeError:

a = np.array([0b1100, 0b1010], dtype=np.uint8)
b = np.array([0b1010, 0b1100], dtype=np.uint8)
print(a & b)        # array([8, 8], dtype=uint8)
print(a | b)        # array([14, 14], dtype=uint8)
print(a ^ b)        # array([6, 6], dtype=uint8)

一元運算子 ~ 會對整數陣列執行位元 NOT 運算。

位移運算子 <<>> 在 Python 運算子層級並未連接實作。其函式形式 left_shift()right_shift() 則可運作:

np.left_shift(a, 2)
np.right_shift(b, 1)

6.8.3. 比較運算

==!=<<=>>= 全都會傳回一個廣播形狀的 bool ndarray:

a = np.array([1, 2, 3, 4, 5], dtype=np.uint8)
print(a < 3)
# array([True, True, False, False, False], dtype=bool)

這個布林結果正是 索引選取與重新排列 所使用的內容。

6.8.3.1. 左側規則

與純量比較時,ndarray 必須位於關係運算子的左側a > 2 可運作;2 < a 則會引發 TypeError。若需對稱形式,請使用函式名稱:

np.greater(5, a)        # 5 > a, element-wise
np.less(5, a)           # 5 < a, element-wise
np.equal(5, a)          # 5 == a, element-wise
np.not_equal(5, a)      # 5 != a, element-wise

6.8.4. 一元運算子

  • +a -- 傳回陣列的副本。

  • -a -- 取負。在無號 dtype 上,值會以模 \(2^N\) 繞回,方式與二元運算子相同。

  • abs(a) -- 逐元素絕對值。在無號 dtype 上,會傳回一份副本而不進行計算。

  • ~a -- 位元反轉(僅限整數陣列)。

  • len(a) -- 傳回第一個軸的長度,符合 Python 序列的慣例。

6.8.5. 缺少的功能

比較運算與部分位元運算的右側運算子,並未以算術運算子那樣的方式實作。當 ndarray 會落在右側時,請使用(上方的)函式形式。

支援的運算子完整清單及其遵循的向上轉型規則,請參閱 numpy --- 與 numpy 相容的陣列運算