こんにちは、Tech Samuraiです!
Pythonでデータ分析や機械学習、科学技術計算を行う際、避けては通れないのが**行列計算**です。特に、行列同士の積は頻繁に登場します。これまで、多くのPythonistaはNumPyの`np.dot()`関数を使ってこの計算を行ってきました。
result = np.dot(A, B)
この書き方はもちろん正しいのですが、複数の行列を連続して掛ける場合など、コードが少し読みにくくなることがありました。
result = np.dot(np.dot(A, B), C) # カッコが増えていく…
しかし、Python 3.5以降、この行列積の計算を、まるで数式のように美しく、そして直感的に書ける`@`演算子が登場したことをご存知ですか? 今回は、このモダンな`@`演算子の使い方と、`np.dot()`との違いについて探検します!
行列積のための「@」演算子とは?
`@`演算子は、行列の積を計算するために導入された、新しい中置演算子です。NumPyライブラリでは、この`@`演算子が`np.matmul()`関数(行列積を計算する関数)に割り当てられています。
これにより、`np.dot(A, B)`と書いていたものが、数学の教科書で見るように`A @ B`と書けるようになりました。これにより、コードの可読性が劇的に向上します。
実践:`np.dot`と`@`を比較してみよう
それでは、実際に両方の方法で計算を行い、結果が同じになることを確認してみましょう。今回は、行列とベクトルの積を計算してみます。
1. プロジェクトの準備
Ryeを使っている方は、新しいプロジェクトでNumPyをインストールしましょう。
mkdir numpy-matmul-test
cd numpy-matmul-test
rye init
rye add numpy
2. 比較用のPythonスクリプト
以下のコードを`main.py`として保存してください。
import numpy as np
def main():
"""
行列とベクトルの積を np.dot と @ 演算子で比較するサンプル
"""
# 3x3の行列を定義
matrix_a = np.array([
[1, 2, 3],
[4, 5, 6],
[7, 8, 9]
])
# 3要素のベクトルを定義
vector_b = np.array([1, 2, 3])
print("--- 行列とベクトルの積の計算 ---")
print("行列 A:\n", matrix_a)
print("\nベクトル b:\n", vector_b)
print("-" * 20)
# --- 方法1: np.dot を使用 ---
print("1. np.dot() を使った計算結果:")
result_with_dot = np.dot(matrix_a, vector_b)
print(result_with_dot)
# --- 方法2: @ 演算子を使用 ---
print("\n2. @ 演算子を使った計算結果:")
result_with_at = matrix_a @ vector_b
print(result_with_at)
# --- 結果の確認 ---
# np.allclose() で、2つの結果が実質的に等しいかを確認
if np.allclose(result_with_dot, result_with_at):
print("\n✅ 両方の計算結果は同じです。")
else:
print("\n❌ 計算結果が異なります。")
if __name__ == "__main__":
main()
3. 実行結果
ターミナルで`rye run python main.py`を実行します。
--- 行列とベクトルの積の計算 ---
行列 A:
[[1 2 3]
[4 5 6]
[7 8 9]]
ベクトル b:
[1 2 3]
--------------------
1. np.dot() を使った計算結果:
[14 32 50]
2. @ 演算子を使った計算結果:
[14 32 50]
✅ 両方の計算結果は同じです。
見事に、両方の計算結果が一致しましたね!
np.dotと@の微妙な違い(補足)
ほとんどの場合、`np.dot`と`@`は同じように使えますが、厳密には少しだけ挙動が違う点があります。
- `@` (`np.matmul`) は、2次元以上の配列(行列)の積に特化しています。
- `np.dot` は、より多機能で、1次元配列(ベクトル)同士の内積や、ベクトルと行列の積など、より広い範囲の計算を扱えます。
しかし、**2次元の行列同士の積を計算する場合は、可読性の観点から`@`演算子を使うことが、現代のPythonコーディングのベストプラクティス**とされています。
まとめ
今回は、NumPyにおける行列積のモダンな書き方、`@`演算子について探検しました。
result = matrix_a @ matrix_b @ matrix_c
このように、`@`演算子を使うことで、関数呼び出しのネスト(入れ子)を避け、より数学的な表現に近い、クリーンで直感的なコードを書くことができます。あなたのデータ分析や科学技術計算のコードを、よりエレガントにするために、ぜひこの`@`演算子を活用してみてください!
コメント