概要(行列計算は「配列の形をそろえて、演算子と線形代数APIに載せる」)
NumPyの行列計算は、2次元配列(ndarray)を使って加算・減算・要素積・行列積・転置・逆行列・行列式・固有値・連立方程式の解などを高速に扱います。初心者がまず押さえるのは「行と列の形状(shape)」「要素ごとの演算と“行列積”の違い」「@(行列積)とlinalg系関数の使い分け」です。これだけで、多くの実務的な行列処理が安全に書けます。
行列の作り方と基本操作(shape・転置・加減算・要素積)
行列の作成と形の確認
import numpy as np
A = np.array([[1, 2], [3, 4]], dtype=np.float64) # 2×2行列
B = np.array([[5, 6], [7, 8]], dtype=np.float64)
print(A.shape) # (2, 2)
print(A.ndim) # 2
Pythonshapeは「(行数, 列数)」。演算の可否はshapeの整合(列数と行数の一致)で決まります。
加算・減算と要素ごとの掛け算(アダマール積)
print(A + B) # 同形なら要素ごとに足し算
print(A - B)
print(A * B) # 要素積(行列積ではない)
PythonA*Bは要素ごとの掛け算です。線形代数の“行列積”とは別物なので注意。
転置(transpose)で行列の向きを変える
AT = A.T
print(AT) # 行と列が入れ替わる
Python多くの演算(内積や行列積)で、転置は形状合わせに重要です。
行列積の基礎(@ 演算子・dot・ブロードキャストの違い)
行列積は @(または np.dot)
C = A @ B # 行列積(2×2 @ 2×2 → 2×2)
print(C)
# ベクトル×行列、行列×ベクトル
v = np.array([1, 0], dtype=np.float64) # 2次元ベクトル
left = v @ A # (2,) @ (2,2) → (2,)
right = A @ v # (2,2) @ (2,) → (2,)
Python行列積は「左の行数 × 右の列数」の新しい行列を作ります。左の列数と右の行数が一致している必要があります。
要素演算との区別(混同しない)
- A*B は要素積(同形が必要)。
- A@B は行列積(左の列数=右の行数が必要)。 分析で“線形結合”を扱うなら必ず @ を使います。
ブロードキャストは「形を自動拡張」だが、行列積とは別
row = np.array([1, 2, 3]) # (3,)
col = np.array([[10], [20]]) # (2,1)
grid = col + row # (2,3) へ拡張されて要素和
Pythonブロードキャストは要素演算用。線形代数の掛け算は @ を使う、が鉄則です。
線形代数API(逆行列・行列式・固有値・連立方程式)
逆行列(正則な正方行列のみ)
A = np.array([[1, 2], [3, 4]], dtype=np.float64)
A_inv = np.linalg.inv(A)
print(A_inv)
print(A @ A_inv) # ほぼ単位行列になる(数値誤差あり)
Python逆行列は「Aを打ち消す行列」。特異(det=0)な行列は逆行列を持てないため、例外や数値不安定に注意。
行列式(det)
detA = np.linalg.det(A)
print(detA) # 0なら特異(逆行列なし)
Python行列式は“体積スケール”や逆行列の存在判定に役立ちます。
固有値・固有ベクトル
vals, vecs = np.linalg.eig(A)
print(vals) # 固有値
print(vecs) # 対応する固有ベクトル(列方向に並ぶ)
Python行列が空間をどう伸縮・回転するかの“軸”を示します。主成分分析や安定性分析に関係します。
連立一次方程式 Ax = b の解(逆行列よりsolveを優先)
A = np.array([[3, 2], [1, 2]], dtype=np.float64)
b = np.array([5, 5], dtype=np.float64)
x = np.linalg.solve(A, b)
print(x)
Python逆行列で x = A_inv @ b とするより、solveは高速・安定です。実務は必ずsolveを使いましょう。
実務で使う行列の作法(単位行列・スタック・ブロック・バッチ計算)
単位行列・ゼロ行列・乱数行列
I = np.eye(3, dtype=np.float64) # 3×3 単位行列
Z = np.zeros((2, 3), dtype=np.float64)
R = np.random.default_rng(0).normal(size=(4, 4)) # 乱数行列
Python単位行列は「何もしない変換」。検算や初期化でよく使います。
行列の結合(縦・横)
A = np.array([[1, 2], [3, 4]], dtype=np.float64)
B = np.array([[5, 6], [7, 8]], dtype=np.float64)
V = np.vstack([A, B]) # 4×2
H = np.hstack([A, B]) # 2×4
Pythonブロック行列やデータ結合の基礎です。shapeの整合に注意。
バッチで複数行列を同時処理(内積・行列積)
X = np.random.default_rng(0).normal(size=(100, 20)) # 100×20
W = np.random.default_rng(1).normal(size=(20, 10)) # 20×10
Y = X @ W # 100×10
Pythonループを回さずに“まとめて”行列積で処理します。ベクトル化が高速化の鍵。
変換と幾何(回転・拡大・平行移動・射影)
2D回転行列で一括回転
theta = np.deg2rad(30)
R = np.array([[np.cos(theta), -np.sin(theta)],
[np.sin(theta), np.cos(theta)]], dtype=np.float64)
pts = np.array([[1,0],[0,1],[1,1]], dtype=np.float64) # N×2
rot = pts @ R.T
print(rot)
Python行列積でN点を一気に回転。スケールやせん断も行列積で合成できます。
平行移動は加算、射影は @ と正規化
shift = np.array([2, -1], dtype=np.float64)
moved = pts + shift # 平行移動
Python幾何の多くは「行列積+加算」で表現できます。順序を間違えると結果が変わるので意図と一致させます。
つまずき対策の深掘り(形状整合・要素積との区別・数値安定・速度)
形状(shape)整合がすべて
行列積は「左の列数=右の行数」。転置(.T)やreshape、Noneで次元を合わせます。shapeが合わないときは「どの軸を合わせたいか」を言語化すると間違いません。
要素積と行列積の取り違えを防ぐ
要素演算は *, 行列積は @。線形代数・変換・モデルの重み計算は @ が基本。誤用は結果がまったく変わるので、コードレビューで必ず確認します。
逆行列はなるべく使わず solve を使う
逆行列は計算コスト・数値誤差が大きくなりがち。Ax=bはnp.linalg.solve、過剰決定ならnp.linalg.lstsq(最小二乗)を使うのが定石です。
浮動小数の誤差と正則性
detが極端に小さい行列は不安定です。スケーリング(標準化)や条件数の確認、正則化(例:対角へ微小値追加)で安定化を図ります。
速度は“ベクトル化とBLAS”
@ や np.dot はBLAS/LAPACKに乗るため高速。Pythonループは使わず、可能な限り配列演算に寄せます。dtypeを揃え、不要コピーを避けるとさらに速くなります。
例題(実務で効く最小セットを一気に体へ)
連立方程式の解と検算
A = np.array([[2, 1], [5, 3]], dtype=np.float64)
b = np.array([4, 13], dtype=np.float64)
x = np.linalg.solve(A, b)
print("x =", x)
print("check =", A @ x) # bに戻る
Pythonsolveで確実に、@で検算まで短く書けます。
最小二乗で近似直線を当てる
X = np.array([[1,1],[1,2],[1,3],[1,4]], dtype=np.float64) # 先頭列は定数項
y = np.array([1.2, 2.8, 3.1, 3.9], dtype=np.float64)
beta, *_ = np.linalg.lstsq(X, y, rcond=None)
print("intercept, slope =", beta)
Python逆行列を使わず、lstsqで安定して回帰係数を求めます。
主成分分析の入口(共分散→固有分解)
X = np.random.default_rng(0).normal(size=(100, 3))
Xc = X - X.mean(axis=0)
Cov = (Xc.T @ Xc) / (len(Xc) - 1)
vals, vecs = np.linalg.eig(Cov)
print("eigenvalues =", vals) # 分散(重要度)
print("eigenvectors =", vecs) # 主成分の方向
Python固有分解で“軸”と“寄与度”が見えます。PCAの基本アイデアです。
まとめ(「@で行列積」「linalgで解く」「shapeをそろえる」だけで安定する)
行列計算の核は、shapeを正しくそろえ、要素演算と行列積を混同せず、線形代数API(solve・det・inv・eig)に載せることです。逆行列は避け、連立方程式はsolve、回帰はlstsq。転置・スタック・単位行列で形を整え、幾何変換は行列積でまとめて適用。これらの型を体に入れれば、初心者でも“短く速く正確な”行列コードを自信を持って書けます。
