【Python/NumPy】行列積は「@」を使おう!np.dotよりモダンで直感的な書き方

ALL

こんにちは、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

このように、`@`演算子を使うことで、関数呼び出しのネスト(入れ子)を避け、より数学的な表現に近い、クリーンで直感的なコードを書くことができます。あなたのデータ分析や科学技術計算のコードを、よりエレガントにするために、ぜひこの`@`演算子を活用してみてください!

コメント

タイトルとURLをコピーしました