NumPyの最大の特徴の一つが、配列のすべての要素に対して一括で関数を適用できる「ユニバーサル関数(Universal Functions、略して ufunc)」です。
Python標準の for ループを使って一つずつ計算するよりも、圧倒的に高速に処理でき、コードもシンプルになります。
目次
実行可能なサンプルコード
以下のコードは、三角関数(sin)、平方根(sqrt)、指数関数(exp)などを配列全体に適用する例です。
import numpy as np
def ufunc_demo():
print("=== 1. 三角関数の計算 (ユーザー例) ===")
# 0から9までの配列を作成
x = np.arange(0, 10)
print(f"Original x: {x}")
# 配列の全要素に対して sin を計算
# Python標準の math.sin(x) だとエラーになりますが、np.sin(x) なら可能です
y = np.sin(x)
print(f"np.sin(x): {y}")
print("\n=== 2. その他の数学関数 ===")
# 平方根 (Square Root)
x2 = np.array([1, 4, 9, 16])
print(f"Original x2: {x2}")
print(f"np.sqrt(x2): {np.sqrt(x2)}") # [1. 2. 3. 4.]
# 指数関数 (Exponential function, e^x)
print(f"np.exp(x2): {np.exp(x2)}")
print("\n=== 3. 配列同士の演算(四則演算のufunc) ===")
a = np.array([10, 20, 30])
b = np.array([1, 2, 3])
# 通常の演算子も内部ではufunc(np.addなど)として処理されます
print(f"a + b: {a + b}") # np.add(a, b) と同じ
print(f"a * b: {a * b}") # np.multiply(a, b) と同じ
print(f"a ** 2: {a ** 2}") # np.power(a, 2) と同じ
if __name__ == "__main__":
ufunc_demo()
解説:ユニバーサル関数のメリット
1. 要素ごとの計算 (Element-wise)
np.sin(x) のように書くだけで、x[0], x[1], … のすべてに対して sin の計算が行われます。これを「要素ごとの計算」と呼びます。
2. 高速な処理 (Vectorization)
Pythonの for ループは処理速度が遅いですが、NumPyのユニバーサル関数はC言語レベルで最適化されたループを使用しているため、大量のデータを扱う際に数倍〜数百倍の速度が出ることがあります。
主要なユニバーサル関数一覧
| 関数名 | 説明 | 演算子での代用 |
np.add(x, y) | 足し算 | x + y |
np.subtract(x, y) | 引き算 | x - y |
np.multiply(x, y) | 掛け算 | x * y |
np.divide(x, y) | 割り算 | x / y |
np.power(x, y) | 累乗 | x ** y |
np.sqrt(x) | 平方根 | なし |
np.sin(x), np.cos(x) | 三角関数 | なし |
np.log(x) | 自然対数 | なし |
np.abs(x) | 絶対値 | なし |
