要素ごとの演算 #
NumPyの四則演算(\( +, -, *, / \))は基本的には要素ごとの演算を行う.
加算なら
x = np.array([1, 2, 3])
y = np.array([4, 5, 6])
x + y # jupyterで出力用出力
array([5, 7, 9])乗算なら
x * y # jupyterで出力用出力
array([4, 10, 18])ブロードキャスト #
NumPy では,形状が異なる配列同士でも,条件を満たせば自動的に形状をそろえて演算できる.この仕組みをブロードキャストという.
普通の四則演算や np.sin(),np.power() などもブロードキャストが適用される.
NumPy は配列の shape を後ろの軸から比較する.次元数が異なる場合は,次元数が少ない配列の先頭にサイズ 1 の軸を補う.その後,各軸のサイズが等しいか,どちらかが 1 であれば演算可能であり,サイズ 1 の軸は自動的に拡張されて揃えられる.
(例)
- A.shape: (2, 3)
- x.shape: (3,)
まず,次元が少ない方の \(x\) の shape は
$$ (3,) → (1, 3) $$のように先頭にサイズ 1 の軸が補われる.次に
$$ (1, 3) → (2, 3) $$のように \(A\) の shapeに揃えられて,その後に要素ごとに演算される.
スカラーと配列 #
x = np.array([1, 2, 3])
x + 2 # jupyterで出力用出力
array([3, 4, 5])- スカラーの 2 は配列 \( x \) の形状に合わせてブロードキャストされ,各要素に加算される.
- 概念的には
array([2, 2, 2])が足されているものと思って良い(実際にそのような配列を内部で作っているわけではない)
異なる形状の配列同士 #
x = np.array([[1, 2, 3],
[4, 5, 6]])
y = np.array([10, 20, 30])
x + y # jupyterで出力用出力
array([[11, 22, 33],
[14, 25, 36]])- \(x\) の形状は \((2, 3)\),\(y\) の形状は \((3,)\)
- \(y\) は \(x\) の形状に合わせてブロードキャストされる
- 概念的には次のような配列が足されていると考えてよい
array([[10, 20, 30],
[10, 20, 30]])ベクトルや行列の積 #
NumPy では @ 演算子または np.matmul() によって線形代数における積を計算できる.
np.dot()も積の計算に使用できるが3次元以上の配列では@と挙動が異なるので注意.現在は@の利用が推奨されている.
これらの演算は四則演算等のブロードキャストとは別物なので注意.
ベクトルの内積 #
x = np.array([0, 1, 2])
y = np.array([3, 4, 5])
x @ y # 0*3 + 1*4 + 2*5出力
14行列とベクトルの積 #
$$ A = \begin{pmatrix} 0 & 1 \\ 2 & 3 \\ \end{pmatrix}, \quad \mathbf{x} = \begin{pmatrix} 0 \\ 1 \\ \end{pmatrix} $$$$ A \mathbf{x} = \begin{pmatrix} 0 & 1 \\ 2 & 3 \\ \end{pmatrix} \begin{pmatrix} 0 \\ 1 \\ \end{pmatrix} = \begin{pmatrix} 1 \\ 3 \\ \end{pmatrix} $$x = np.array([0, 1]) # ベクトル
A = np.array([[0, 1], [2, 3]]) # 行列
A @ x出力
array([1, 3])ここで x @ A のように順番を変えると上記とは異なる計算になるので注意.
@ はブロードキャストとは違なり特別な演算になる.
下記の例ではベクトルは横ベクトルと解釈される.
x @ A出力
array([2, 3])ただし,最終的に得られるのは1次元配列なので,横ベクトルではなくなる.1次元配列は縦横の区別はない.
行列同士の積 #
$$ \begin{pmatrix} 0 & 1 \\ 2 & 3 \\ \end{pmatrix} \begin{pmatrix} 3 & 2 \\ 1 & 0 \\ \end{pmatrix} = \begin{pmatrix} 1 & 0 \\ 9 & 4 \\ \end{pmatrix} $$A = np.array([[0, 1],[2, 3]])
B = np.array([[3, 2], [1, 0]])
A @ B出力
array([[1, 0],
[9, 4]])