{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "# NumPy (2): 行列・テンソル\n", "\n", "このノートブックでは`numpy`モジュールのエイリアス(短縮表記)として`np`を用いる。" ] }, { "cell_type": "code", "execution_count": 1, "metadata": {}, "outputs": [], "source": [ "import numpy as np" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## 行列のオブジェクト\n", "\n", "行列も[np.array](https://numpy.org/doc/stable/reference/generated/numpy.array.html)で作成できる。以下のコードは$3 \\times 4$の行列\n", "\n", "$$\n", "\\pmb{X} = \\left(\\begin{array}{c}\n", "1 & 2 & 3 & 4 \\\\\n", "2 & 3 & 4 & 5 \\\\\n", "3 & 4 & 5 & 6\n", "\\end{array}\\right)\n", "$$\n", "\n", "を定義している。" ] }, { "cell_type": "code", "execution_count": 2, "metadata": {}, "outputs": [], "source": [ "x = np.array([\n", " [1, 2, 3, 4],\n", " [2, 3, 4, 5],\n", " [3, 4, 5, 6]\n", "])" ] }, { "cell_type": "code", "execution_count": 3, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "array([[1, 2, 3, 4],\n", " [2, 3, 4, 5],\n", " [3, 4, 5, 6]])" ] }, "execution_count": 3, "metadata": {}, "output_type": "execute_result" } ], "source": [ "x" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "作成されたオブジェクトの型は[numpy.ndarray](https://numpy.org/doc/stable/reference/generated/numpy.ndarray.html)。" ] }, { "cell_type": "code", "execution_count": 4, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "numpy.ndarray" ] }, "execution_count": 4, "metadata": {}, "output_type": "execute_result" } ], "source": [ "type(x)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "行列の次元数(軸の数)は2(`x`は2次元の行列)。" ] }, { "cell_type": "code", "execution_count": 5, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "2" ] }, "execution_count": 5, "metadata": {}, "output_type": "execute_result" } ], "source": [ "x.ndim" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "各次元の要素数を表すタプル。`x`の1次元目には$3$個、2次元目には$4$個の要素が格納されている。すなわち、$3 \\times 4$の行列であることを表している。" ] }, { "cell_type": "code", "execution_count": 6, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "(3, 4)" ] }, "execution_count": 6, "metadata": {}, "output_type": "execute_result" } ], "source": [ "x.shape" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "オブジェクトに含まれる要素数。`x`は$3 \\times 4$の行列なので、全要素数は$12$。" ] }, { "cell_type": "code", "execution_count": 7, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "12" ] }, "execution_count": 7, "metadata": {}, "output_type": "execute_result" } ], "source": [ "x.size" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "`x`の各要素は整数である。" ] }, { "cell_type": "code", "execution_count": 8, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "dtype('int64')" ] }, "execution_count": 8, "metadata": {}, "output_type": "execute_result" } ], "source": [ "x.dtype" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## 行列の要素\n", "\n", "$$\n", "\\pmb{X} = \\left(\\begin{array}{c}\n", "1 & 2 & 3 & 4 \\\\\n", "2 & 3 & 4 & 5 \\\\\n", "3 & 4 & 5 & 6\n", "\\end{array}\\right)\n", "$$" ] }, { "cell_type": "code", "execution_count": 9, "metadata": {}, "outputs": [], "source": [ "x = np.array([\n", " [1, 2, 3, 4],\n", " [2, 3, 4, 5],\n", " [3, 4, 5, 6]\n", "])" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "行列$\\pmb{X}$の$2$行$1$列目の要素$X_{2,1}$(インデックスが$0$から始まることに注意)。" ] }, { "cell_type": "code", "execution_count": 10, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "4" ] }, "execution_count": 10, "metadata": {}, "output_type": "execute_result" } ], "source": [ "x[2][1]" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "要素$X_{2,1}$に以下のようにアクセスすることも可能。" ] }, { "cell_type": "code", "execution_count": 11, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "4" ] }, "execution_count": 11, "metadata": {}, "output_type": "execute_result" } ], "source": [ "x[2,1]" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "行列$\\pmb{X}$の1次元目(行)で1番目の行$\\pmb{X}_{1,:}$を取り出す(1行目の行ベクトル)。" ] }, { "cell_type": "code", "execution_count": 12, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "array([2, 3, 4, 5])" ] }, "execution_count": 12, "metadata": {}, "output_type": "execute_result" } ], "source": [ "x[1]" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "行列$\\pmb{X}$の2次元目(列)で1番目の列$\\pmb{X}_{:,1}$を取り出す(1列目の列ベクトル)。" ] }, { "cell_type": "code", "execution_count": 13, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "array([2, 3, 4])" ] }, "execution_count": 13, "metadata": {}, "output_type": "execute_result" } ], "source": [ "x[:,1]" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "行列$\\pmb{X}$の1行目および1列目まで$\\pmb{X}_{0:2,0:2}$を取り出す(つまり、左上から$2 \\times 2$の部分を取り出す)。" ] }, { "cell_type": "code", "execution_count": 14, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "array([[1, 2],\n", " [2, 3]])" ] }, "execution_count": 14, "metadata": {}, "output_type": "execute_result" } ], "source": [ "x[:2,:2]" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "スライスで取り出す要素をリストで指定してもよい。" ] }, { "cell_type": "code", "execution_count": 15, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "array([1, 3, 5])" ] }, "execution_count": 15, "metadata": {}, "output_type": "execute_result" } ], "source": [ "x[[0,1,2],[0,1,2]]" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "行列$\\pmb{X}$の要素$X_{0,0} \\leftarrow 0$" ] }, { "cell_type": "code", "execution_count": 16, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "array([[0, 2, 3, 4],\n", " [2, 3, 4, 5],\n", " [3, 4, 5, 6]])" ] }, "execution_count": 16, "metadata": {}, "output_type": "execute_result" } ], "source": [ "x[0][0] = 0\n", "x" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "行列$\\pmb{X}$の0行目の行ベクトル$\\pmb{X}_{0,:} \\leftarrow \\boldsymbol{0}$" ] }, { "cell_type": "code", "execution_count": 17, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "array([[0, 0, 0, 0],\n", " [2, 3, 4, 5],\n", " [3, 4, 5, 6]])" ] }, "execution_count": 17, "metadata": {}, "output_type": "execute_result" } ], "source": [ "x[0] = 0\n", "x" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "行列$\\pmb{X}$の0列の列ベクトル$\\pmb{X}_{:,0} \\leftarrow \\boldsymbol{0}$" ] }, { "cell_type": "code", "execution_count": 18, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "array([[0, 0, 0, 0],\n", " [0, 3, 4, 5],\n", " [0, 4, 5, 6]])" ] }, "execution_count": 18, "metadata": {}, "output_type": "execute_result" } ], "source": [ "x[:,0] = 0\n", "x" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "$\\pmb{X}_{0,:} \\leftarrow \\left(\\begin{array}{c}\n", "0 & 1 & 2 & 3\n", "\\end{array}\\right)$" ] }, { "cell_type": "code", "execution_count": 19, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "array([[0, 1, 2, 3],\n", " [0, 3, 4, 5],\n", " [0, 4, 5, 6]])" ] }, "execution_count": 19, "metadata": {}, "output_type": "execute_result" } ], "source": [ "x[0] = np.arange(4)\n", "x" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## 行列の算術演算\n", "\n", "$$\n", "\\pmb{X} = \\left(\\begin{array}{c}\n", "1 & 2 & 3 \\\\\n", "2 & 3 & 4\n", "\\end{array}\\right),\n", "\\pmb{Y} = \\left(\\begin{array}{c}\n", "1 & 3 & 5 \\\\\n", "2 & 4 & 6 \\\\\n", "\\end{array}\\right)\n", "$$\n", "\n", "に対して、様々な演算を見ていく。" ] }, { "cell_type": "code", "execution_count": 20, "metadata": {}, "outputs": [], "source": [ "x = np.array([\n", " [1, 2, 3],\n", " [2, 3, 4],\n", "], dtype='float')\n", "y = np.array([\n", " [1, 3, 5],\n", " [2, 4, 6],\n", "], dtype='float')" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "行列の和\n", "\n", "$$\n", "\\pmb{X} + \\pmb{Y} = \\left(\\begin{array}{c}\n", "1 & 2 & 3 \\\\\n", "2 & 3 & 4\n", "\\end{array}\\right) + \\left(\\begin{array}{c}\n", "1 & 3 & 5 \\\\\n", "2 & 4 & 6 \\\\\n", "\\end{array}\\right) = \\left(\\begin{array}{c}\n", "1+1 & 2+3 & 3+5 \\\\\n", "2+2 & 3+4 & 4+6 \\\\\n", "\\end{array}\\right) = \\left(\\begin{array}{c}\n", "2 & 5 & 8 \\\\\n", "4 & 7 & 10 \\\\\n", "\\end{array}\\right)\n", "$$" ] }, { "cell_type": "code", "execution_count": 21, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "array([[ 2., 5., 8.],\n", " [ 4., 7., 10.]])" ] }, "execution_count": 21, "metadata": {}, "output_type": "execute_result" } ], "source": [ "x + y" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "行列の差\n", "\n", "$$\n", "\\pmb{X} - \\pmb{Y} = \\left(\\begin{array}{c}\n", "1 & 2 & 3 \\\\\n", "2 & 3 & 4\n", "\\end{array}\\right) - \\left(\\begin{array}{c}\n", "1 & 3 & 5 \\\\\n", "2 & 4 & 6 \\\\\n", "\\end{array}\\right) = \\left(\\begin{array}{c}\n", "1-1 & 2-3 & 3-5 \\\\\n", "2-2 & 3-4 & 4-6 \\\\\n", "\\end{array}\\right) = \\left(\\begin{array}{c}\n", "0 & -1 & -2 \\\\\n", "0 & -1 & -2 \\\\\n", "\\end{array}\\right)\n", "$$" ] }, { "cell_type": "code", "execution_count": 22, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "array([[ 0., -1., -2.],\n", " [ 0., -1., -2.]])" ] }, "execution_count": 22, "metadata": {}, "output_type": "execute_result" } ], "source": [ "x - y" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "行列と行列のアダマール積\n", "\n", "$$\n", "\\pmb{X} \\odot \\pmb{Y} = \\left(\\begin{array}{c}\n", "1 & 2 & 3 \\\\\n", "2 & 3 & 4\n", "\\end{array}\\right) \\odot \\left(\\begin{array}{c}\n", "1 & 3 & 5 \\\\\n", "2 & 4 & 6 \\\\\n", "\\end{array}\\right) = \\left(\\begin{array}{c}\n", "1 \\times 1 & 2 \\times 3 & 3 \\times 5 \\\\\n", "2 \\times 2 & 3 \\times 4 & 4 \\times 6 \\\\\n", "\\end{array}\\right) = \\left(\\begin{array}{c}\n", "1 & 6 & 15 \\\\\n", "4 & 12 & 24 \\\\\n", "\\end{array}\\right)\n", "$$" ] }, { "cell_type": "code", "execution_count": 26, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "array([[ 1., 6., 15.],\n", " [ 4., 12., 24.]])" ] }, "execution_count": 26, "metadata": {}, "output_type": "execute_result" } ], "source": [ "x * y" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "スカラーと行列の和\n", "\n", "$$\n", "1 + \\pmb{X} = \\left(\\begin{array}{c}\n", "1 & 1 & 1 \\\\\n", "1 & 1 & 1\n", "\\end{array}\\right) + \\left(\\begin{array}{c}\n", "1 & 2 & 3 \\\\\n", "2 & 3 & 4\n", "\\end{array}\\right) = \\left(\\begin{array}{c}\n", "2 & 3 & 4 \\\\\n", "3 & 4 & 5 \\\\\n", "\\end{array}\\right)\n", "$$" ] }, { "cell_type": "code", "execution_count": 24, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "array([[2., 3., 4.],\n", " [3., 4., 5.]])" ] }, "execution_count": 24, "metadata": {}, "output_type": "execute_result" } ], "source": [ "1 + x" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "スカラーと行列の差\n", "\n", "$$\n", "1 - \\pmb{X} = \\left(\\begin{array}{c}\n", "1 & 1 & 1 \\\\\n", "1 & 1 & 1\n", "\\end{array}\\right) - \\left(\\begin{array}{c}\n", "1 & 2 & 3 \\\\\n", "2 & 3 & 4\n", "\\end{array}\\right) = \\left(\\begin{array}{c}\n", "0 & -1 & -2 \\\\\n", "-1 & -2 & -3 \\\\\n", "\\end{array}\\right)\n", "$$" ] }, { "cell_type": "code", "execution_count": 25, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "array([[ 0., -1., -2.],\n", " [-1., -2., -3.]])" ] }, "execution_count": 25, "metadata": {}, "output_type": "execute_result" } ], "source": [ "1 - x" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "行列のスカラー倍\n", "\n", "$$\n", "2\\pmb{X} = \\left(\\begin{array}{c}\n", "2 & 2 & 2 \\\\\n", "2 & 2 & 2\n", "\\end{array}\\right) \\odot \\left(\\begin{array}{c}\n", "1 & 2 & 3 \\\\\n", "2 & 3 & 4\n", "\\end{array}\\right) = \\left(\\begin{array}{c}\n", "2 \\times 1 & 2 \\times 2 & 2 \\times 3 \\\\\n", "2 \\times 2 & 2 \\times 3 & 2 \\times 4\n", "\\end{array}\\right) = \\left(\\begin{array}{c}\n", "2 & 4 & 6 \\\\\n", "4 & 6 & 8 \\\\\n", "\\end{array}\\right)\n", "$$" ] }, { "cell_type": "code", "execution_count": 23, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "array([[2., 4., 6.],\n", " [4., 6., 8.]])" ] }, "execution_count": 23, "metadata": {}, "output_type": "execute_result" } ], "source": [ "2 * x" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "転置行列\n", "\n", "$$\n", "Z = Y^\\top = \\left(\\begin{array}{c}\n", "1 & 3 & 5 \\\\\n", "2 & 4 & 6 \\\\\n", "\\end{array}\\right)^\\top\n", "= \\left(\\begin{array}{c}\n", "1 & 2 \\\\\n", "3 & 4 \\\\\n", "5 & 6\n", "\\end{array}\\right)\n", "$$" ] }, { "cell_type": "code", "execution_count": 27, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "array([[1., 2.],\n", " [3., 4.],\n", " [5., 6.]])" ] }, "execution_count": 27, "metadata": {}, "output_type": "execute_result" } ], "source": [ "z = y.T\n", "z" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "行列積\n", "\n", "\\begin{align*}\n", "XZ &= \\left(\\begin{array}{c}\n", "1 & 2 & 3 \\\\\n", "2 & 3 & 4\n", "\\end{array}\\right) \\left(\\begin{array}{c}\n", "1 & 2 \\\\\n", "3 & 4 \\\\\n", "5 & 6\n", "\\end{array}\\right) \\\\\n", "&= \\left(\\begin{array}{c}\n", "1 \\times 1 + 2 \\times 3 + 3 \\times 5 & 1 \\times 2 + 2 \\times 4 + 3 \\times 6 \\\\\n", "2 \\times 1 + 3 \\times 3 + 4 \\times 5 & 2 \\times 2 + 3 \\times 4 + 4 \\times 6 \\\\\n", "\\end{array}\\right) \\\\\n", "&= \\left(\\begin{array}{c}\n", "22 & 28 \\\\\n", "31 & 40 \\\\\n", "\\end{array}\\right)\n", "\\end{align*}" ] }, { "cell_type": "code", "execution_count": 28, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "array([[22., 28.],\n", " [31., 40.]])" ] }, "execution_count": 28, "metadata": {}, "output_type": "execute_result" } ], "source": [ "np.dot(x, z)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "行列積$XZ$は`@`演算子で書くこともできる。" ] }, { "cell_type": "code", "execution_count": 29, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "array([[22., 28.],\n", " [31., 40.]])" ] }, "execution_count": 29, "metadata": {}, "output_type": "execute_result" } ], "source": [ "x @ z" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "行列の累乗\n", "\n", "$$\n", "X^2 = \\left(\\begin{array}{c}\n", "1 & 2 & 3 \\\\\n", "2 & 3 & 4\n", "\\end{array}\\right)^2 = \\left(\\begin{array}{c}\n", "1^2 & 2^2 & 3^2 \\\\\n", "2^2 & 3^2 & 4^2\n", "\\end{array}\\right) = \\left(\\begin{array}{c}\n", "1 & 4 & 9 \\\\\n", "4 & 9 & 16\n", "\\end{array}\\right)\n", "$$" ] }, { "cell_type": "code", "execution_count": 30, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "array([[ 1., 4., 9.],\n", " [ 4., 9., 16.]])" ] }, "execution_count": 30, "metadata": {}, "output_type": "execute_result" } ], "source": [ "x ** 2" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "行列の要素数が合わないなどで、演算が実行できないときはエラーとなる。例えば行列積$XY$を計算するには、$X$の列の数と$Y$の行の数が一致する必要がある。" ] }, { "cell_type": "code", "execution_count": 31, "metadata": { "tags": [ "raises-exception" ] }, "outputs": [ { "ename": "ValueError", "evalue": "matmul: Input operand 1 has a mismatch in its core dimension 0, with gufunc signature (n?,k),(k,m?)->(n?,m?) (size 2 is different from 3)", "output_type": "error", "traceback": [ "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", "\u001b[0;31mValueError\u001b[0m Traceback (most recent call last)", "\u001b[0;32m\u001b[0m in \u001b[0;36m\u001b[0;34m\u001b[0m\n\u001b[0;32m----> 1\u001b[0;31m \u001b[0mx\u001b[0m \u001b[0;34m@\u001b[0m \u001b[0my\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m", "\u001b[0;31mValueError\u001b[0m: matmul: Input operand 1 has a mismatch in its core dimension 0, with gufunc signature (n?,k),(k,m?)->(n?,m?) (size 2 is different from 3)" ] } ], "source": [ "x @ y" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## 行列の様々な作成方法" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "零行列。" ] }, { "cell_type": "code", "execution_count": 33, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "array([[0., 0., 0., 0.],\n", " [0., 0., 0., 0.],\n", " [0., 0., 0., 0.]])" ] }, "execution_count": 33, "metadata": {}, "output_type": "execute_result" } ], "source": [ "np.zeros((3, 4))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "$X$と同じ形状の零行列。" ] }, { "cell_type": "code", "execution_count": 32, "metadata": {}, "outputs": [], "source": [ "x = np.array([\n", " [0, 1],\n", " [1, 2],\n", " [2, 3],\n", "])" ] }, { "cell_type": "code", "execution_count": 34, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "array([[0, 0],\n", " [0, 0],\n", " [0, 0]])" ] }, "execution_count": 34, "metadata": {}, "output_type": "execute_result" } ], "source": [ "np.zeros_like(x)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "要素がすべて$1$の行列。" ] }, { "cell_type": "code", "execution_count": 35, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "array([[1., 1., 1., 1.],\n", " [1., 1., 1., 1.],\n", " [1., 1., 1., 1.]])" ] }, "execution_count": 35, "metadata": {}, "output_type": "execute_result" } ], "source": [ "np.ones((3, 4))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "$X$と同じ形状で要素がすべて$1$の行列。" ] }, { "cell_type": "code", "execution_count": 36, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "array([[1, 1],\n", " [1, 1],\n", " [1, 1]])" ] }, "execution_count": 36, "metadata": {}, "output_type": "execute_result" } ], "source": [ "np.ones_like(x)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "任意の値で初期化した行列。" ] }, { "cell_type": "code", "execution_count": 37, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "array([[-2., -2., -2., -2.],\n", " [-2., -2., -2., -2.],\n", " [-2., -2., -2., -2.]])" ] }, "execution_count": 37, "metadata": {}, "output_type": "execute_result" } ], "source": [ "np.full((3, 4), -2.)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "$X$と同じ形状で任意の値で初期化した行列。" ] }, { "cell_type": "code", "execution_count": 38, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "array([[-2, -2],\n", " [-2, -2],\n", " [-2, -2]])" ] }, "execution_count": 38, "metadata": {}, "output_type": "execute_result" } ], "source": [ "np.full_like(x, -2.)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "単位行列(必ず正方行列となる)。" ] }, { "cell_type": "code", "execution_count": 39, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "array([[1., 0., 0., 0.],\n", " [0., 1., 0., 0.],\n", " [0., 0., 1., 0.],\n", " [0., 0., 0., 1.]])" ] }, "execution_count": 39, "metadata": {}, "output_type": "execute_result" } ], "source": [ "np.identity(4)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "対角要素が$1$、それ以外の要素が$0$である行列(正方行列でなくても作成できる)。" ] }, { "cell_type": "code", "execution_count": 40, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "array([[1., 0., 0., 0.],\n", " [0., 1., 0., 0.],\n", " [0., 0., 1., 0.]])" ] }, "execution_count": 40, "metadata": {}, "output_type": "execute_result" } ], "source": [ "np.eye(3, 4)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "[np.eye](https://numpy.org/doc/stable/reference/generated/numpy.eye.html)でも単位行列を作成できる。" ] }, { "cell_type": "code", "execution_count": 41, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "array([[1., 0., 0., 0.],\n", " [0., 1., 0., 0.],\n", " [0., 0., 1., 0.],\n", " [0., 0., 0., 1.]])" ] }, "execution_count": 41, "metadata": {}, "output_type": "execute_result" } ], "source": [ "np.eye(4)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "ベクトルから形状を変更して行列にする例。" ] }, { "cell_type": "code", "execution_count": 42, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "array([[ 0, 1, 2, 3],\n", " [ 4, 5, 6, 7],\n", " [ 8, 9, 10, 11]])" ] }, "execution_count": 42, "metadata": {}, "output_type": "execute_result" } ], "source": [ "np.arange(12).reshape(3, 4)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "[reshape](https://numpy.org/doc/stable/reference/generated/numpy.ndarray.reshape.html#numpy.ndarray.reshape)メソッドにおいて、いずれかの次元の要素数を-1とすると、他の次元の要素数に基づいてその次元の要素数が推定される。" ] }, { "cell_type": "code", "execution_count": 43, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "array([[ 0, 1, 2, 3, 4, 5],\n", " [ 6, 7, 8, 9, 10, 11]])" ] }, "execution_count": 43, "metadata": {}, "output_type": "execute_result" } ], "source": [ "np.arange(12).reshape(2, -1)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "$[0, 1)$の範囲の一様分布からランダムに要素をサンプルして作った行列。" ] }, { "cell_type": "code", "execution_count": 44, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "array([[0.41138273, 0.56472476, 0.74019377, 0.21415386],\n", " [0.72671417, 0.00608295, 0.73117914, 0.97736548],\n", " [0.27531559, 0.69205105, 0.1033887 , 0.94401989]])" ] }, "execution_count": 44, "metadata": {}, "output_type": "execute_result" } ], "source": [ "np.random.rand(3, 4)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "標準正規分布(平均$0$、分散$1$の正規分布)からランダムに要素を抽出して作った行列。" ] }, { "cell_type": "code", "execution_count": 45, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "array([[-0.10454056, -0.14676112, -0.12848028, 0.62593397],\n", " [-0.82940938, -0.45294596, -0.3850291 , -1.75512478],\n", " [ 0.28350437, 0.54926243, -0.66035861, -0.50153151]])" ] }, "execution_count": 45, "metadata": {}, "output_type": "execute_result" } ], "source": [ "np.random.randn(3, 4)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "正規分布(以下の例では平均$0.5$、分散$2$の正規分布)からランダムに要素を抽出して作った行列。" ] }, { "cell_type": "code", "execution_count": 46, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "array([[ 0.05489919, 0.4101351 , 2.20940252, -1.12757369],\n", " [ 0.18863236, 0.20804204, -0.58426747, 1.76459683],\n", " [-2.4958973 , 4.89609212, -3.17816385, 1.27884234]])" ] }, "execution_count": 46, "metadata": {}, "output_type": "execute_result" } ], "source": [ "np.random.normal(0.5, 2, (3, 4))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## 数学関数\n", "\n", "ベクトルのときに紹介した数学関数は行列でも使える。ただし、必要に応じて演算を行う単位を軸(axis)として指定する。" ] }, { "cell_type": "code", "execution_count": 47, "metadata": {}, "outputs": [], "source": [ "x = np.array([\n", " [ 1, 12, 9, 4],\n", " [ 8, 2, 3, 7],\n", " [ 11, 5, 6, 10],\n", "])" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "行列の要素の和。" ] }, { "cell_type": "code", "execution_count": 48, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "78" ] }, "execution_count": 48, "metadata": {}, "output_type": "execute_result" } ], "source": [ "np.sum(x)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "行列の最初の次元のベクトル(行ベクトル)の和。" ] }, { "cell_type": "code", "execution_count": 49, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "array([20, 19, 18, 21])" ] }, "execution_count": 49, "metadata": {}, "output_type": "execute_result" } ], "source": [ "np.sum(x, axis=0)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "行列の2番目の次元のベクトル(列ベクトル)の和。" ] }, { "cell_type": "code", "execution_count": 50, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "array([26, 20, 32])" ] }, "execution_count": 50, "metadata": {}, "output_type": "execute_result" } ], "source": [ "np.sum(x, axis=1)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "行列の要素の積。" ] }, { "cell_type": "code", "execution_count": 51, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "479001600" ] }, "execution_count": 51, "metadata": {}, "output_type": "execute_result" } ], "source": [ "np.prod(x)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "行列の最初の次元のベクトル(行ベクトル)の積。" ] }, { "cell_type": "code", "execution_count": 52, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "array([ 88, 120, 162, 280])" ] }, "execution_count": 52, "metadata": {}, "output_type": "execute_result" } ], "source": [ "np.prod(x, axis=0)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "行列の2番目の次元のベクトル(列ベクトル)の積。" ] }, { "cell_type": "code", "execution_count": 53, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "array([ 432, 336, 3300])" ] }, "execution_count": 53, "metadata": {}, "output_type": "execute_result" } ], "source": [ "np.prod(x, axis=1)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "行列の要素の累積和。" ] }, { "cell_type": "code", "execution_count": 54, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "array([ 1, 13, 22, 26, 34, 36, 39, 46, 57, 62, 68, 78])" ] }, "execution_count": 54, "metadata": {}, "output_type": "execute_result" } ], "source": [ "np.cumsum(x)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "行列の最初の次元のベクトル(行ベクトル)の累積和。" ] }, { "cell_type": "code", "execution_count": 55, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "array([[ 1, 12, 9, 4],\n", " [ 9, 14, 12, 11],\n", " [20, 19, 18, 21]])" ] }, "execution_count": 55, "metadata": {}, "output_type": "execute_result" } ], "source": [ "np.cumsum(x, axis=0)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "行列の2番目の次元のベクトル(列ベクトル)の累積和。" ] }, { "cell_type": "code", "execution_count": 56, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "array([[ 1, 13, 22, 26],\n", " [ 8, 10, 13, 20],\n", " [11, 16, 22, 32]])" ] }, "execution_count": 56, "metadata": {}, "output_type": "execute_result" } ], "source": [ "np.cumsum(x, axis=1)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "行列の要素の累積積。" ] }, { "cell_type": "code", "execution_count": 57, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "array([ 1, 12, 108, 432, 3456, 6912,\n", " 20736, 145152, 1596672, 7983360, 47900160, 479001600])" ] }, "execution_count": 57, "metadata": {}, "output_type": "execute_result" } ], "source": [ "np.cumprod(x)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "行列の最初の次元のベクトル(行ベクトル)の累積積。" ] }, { "cell_type": "code", "execution_count": 58, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "array([[ 1, 12, 9, 4],\n", " [ 8, 24, 27, 28],\n", " [ 88, 120, 162, 280]])" ] }, "execution_count": 58, "metadata": {}, "output_type": "execute_result" } ], "source": [ "np.cumprod(x, axis=0)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "行列の2番目の次元のベクトル(列ベクトル)の累積積。" ] }, { "cell_type": "code", "execution_count": 59, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "array([[ 1, 12, 108, 432],\n", " [ 8, 16, 48, 336],\n", " [ 11, 55, 330, 3300]])" ] }, "execution_count": 59, "metadata": {}, "output_type": "execute_result" } ], "source": [ "np.cumprod(x, axis=1)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "行列の要素の平均。" ] }, { "cell_type": "code", "execution_count": 60, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "6.5" ] }, "execution_count": 60, "metadata": {}, "output_type": "execute_result" } ], "source": [ "np.mean(x)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "行列の最初の次元のベクトル(行ベクトル)の平均。" ] }, { "cell_type": "code", "execution_count": 61, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "array([6.66666667, 6.33333333, 6. , 7. ])" ] }, "execution_count": 61, "metadata": {}, "output_type": "execute_result" } ], "source": [ "np.mean(x, axis=0)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "行列の2番目の次元のベクトル(列ベクトル)の平均。" ] }, { "cell_type": "code", "execution_count": 62, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "array([6.5, 5. , 8. ])" ] }, "execution_count": 62, "metadata": {}, "output_type": "execute_result" } ], "source": [ "np.mean(x, axis=1)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "行列の要素の分散。" ] }, { "cell_type": "code", "execution_count": 63, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "11.916666666666666" ] }, "execution_count": 63, "metadata": {}, "output_type": "execute_result" } ], "source": [ "np.var(x)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "行列の最初の次元のベクトル(行ベクトル)の分散。" ] }, { "cell_type": "code", "execution_count": 64, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "array([17.55555556, 17.55555556, 6. , 6. ])" ] }, "execution_count": 64, "metadata": {}, "output_type": "execute_result" } ], "source": [ "np.var(x, axis=0)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "行列の2番目の次元のベクトル(列ベクトル)の分散。" ] }, { "cell_type": "code", "execution_count": 65, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "array([18.25, 6.5 , 6.5 ])" ] }, "execution_count": 65, "metadata": {}, "output_type": "execute_result" } ], "source": [ "np.var(x, axis=1)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "行列の要素の標準偏差。" ] }, { "cell_type": "code", "execution_count": 66, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "3.452052529534663" ] }, "execution_count": 66, "metadata": {}, "output_type": "execute_result" } ], "source": [ "np.std(x)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "行列の最初の次元のベクトル(行ベクトル)の標準偏差。" ] }, { "cell_type": "code", "execution_count": 67, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "array([4.18993503, 4.18993503, 2.44948974, 2.44948974])" ] }, "execution_count": 67, "metadata": {}, "output_type": "execute_result" } ], "source": [ "np.std(x, axis=0)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "行列の2番目の次元のベクトル(列ベクトル)の標準偏差。" ] }, { "cell_type": "code", "execution_count": 68, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "array([4.27200187, 2.54950976, 2.54950976])" ] }, "execution_count": 68, "metadata": {}, "output_type": "execute_result" } ], "source": [ "np.std(x, axis=1)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "行列の要素の最小値。" ] }, { "cell_type": "code", "execution_count": 69, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "1" ] }, "execution_count": 69, "metadata": {}, "output_type": "execute_result" } ], "source": [ "np.min(x)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "行列の最初の次元のベクトル(行ベクトル)を取り出し、各要素の最小値を取り出したベクトル。" ] }, { "cell_type": "code", "execution_count": 70, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "array([1, 2, 3, 4])" ] }, "execution_count": 70, "metadata": {}, "output_type": "execute_result" } ], "source": [ "np.min(x, axis=0)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "行列の2番目の次元のベクトル(列ベクトル)を取り出し、各要素の最小値を取り出したベクトル。" ] }, { "cell_type": "code", "execution_count": 71, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "array([1, 2, 5])" ] }, "execution_count": 71, "metadata": {}, "output_type": "execute_result" } ], "source": [ "np.min(x, axis=1)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "行列の要素の最大値。" ] }, { "cell_type": "code", "execution_count": 72, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "12" ] }, "execution_count": 72, "metadata": {}, "output_type": "execute_result" } ], "source": [ "np.max(x)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "行列の最初の次元のベクトル(行ベクトル)を取り出し、各要素の最大値を取り出したベクトル。" ] }, { "cell_type": "code", "execution_count": 73, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "array([11, 12, 9, 10])" ] }, "execution_count": 73, "metadata": {}, "output_type": "execute_result" } ], "source": [ "np.max(x, axis=0)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "行列の2番目の次元のベクトル(列ベクトル)を取り出し、各要素の最大値を取り出したベクトル。" ] }, { "cell_type": "code", "execution_count": 74, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "array([12, 8, 11])" ] }, "execution_count": 74, "metadata": {}, "output_type": "execute_result" } ], "source": [ "np.max(x, axis=1)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "行列の最小値に対応するインデックス番号。" ] }, { "cell_type": "code", "execution_count": 75, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "(0, 0)" ] }, "execution_count": 75, "metadata": {}, "output_type": "execute_result" } ], "source": [ "np.unravel_index(x.argmin(), x.shape)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "行列の最大値に対応するインデックス番号。" ] }, { "cell_type": "code", "execution_count": 76, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "(0, 1)" ] }, "execution_count": 76, "metadata": {}, "output_type": "execute_result" } ], "source": [ "np.unravel_index(x.argmax(), x.shape)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## ユニバーサル関数\n", "\n", "ベクトルの場合と同様に、行列に対して[ユニバーサル関数](https://numpy.org/doc/stable/reference/ufuncs.html)を適用すると、要素ごとに数学的な計算を行う。" ] }, { "cell_type": "code", "execution_count": 77, "metadata": {}, "outputs": [], "source": [ "x = np.array([\n", " [ 0, 1],\n", " [-1, 2],\n", "])\n", "theta = np.array([\n", " [ 0, 90],\n", " [-90, 180],\n", "])" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "累乗(`**`と同じ)。" ] }, { "cell_type": "code", "execution_count": 78, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "array([[ 0, 1],\n", " [ 1, 16]])" ] }, "execution_count": 78, "metadata": {}, "output_type": "execute_result" } ], "source": [ "y = np.power(x, 4)\n", "y" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "平方根。" ] }, { "cell_type": "code", "execution_count": 79, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "array([[0., 1.],\n", " [1., 4.]])" ] }, "execution_count": 79, "metadata": {}, "output_type": "execute_result" } ], "source": [ "np.sqrt(y)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "$e$に対する指数" ] }, { "cell_type": "code", "execution_count": 80, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "array([[1. , 2.71828183],\n", " [0.36787944, 7.3890561 ]])" ] }, "execution_count": 80, "metadata": {}, "output_type": "execute_result" } ], "source": [ "y = np.exp(x)\n", "y" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "自然対数" ] }, { "cell_type": "code", "execution_count": 81, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "array([[ 0., 1.],\n", " [-1., 2.]])" ] }, "execution_count": 81, "metadata": {}, "output_type": "execute_result" } ], "source": [ "np.log(y)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "三角関数" ] }, { "cell_type": "code", "execution_count": 82, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "array([[ 0.0000000e+00, 1.0000000e+00],\n", " [-1.0000000e+00, 1.2246468e-16]])" ] }, "execution_count": 82, "metadata": {}, "output_type": "execute_result" } ], "source": [ "np.sin(theta / 360 * 2 * np.pi)" ] }, { "cell_type": "code", "execution_count": 83, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "array([[ 1.000000e+00, 6.123234e-17],\n", " [ 6.123234e-17, -1.000000e+00]])" ] }, "execution_count": 83, "metadata": {}, "output_type": "execute_result" } ], "source": [ "np.cos(theta / 360 * 2 * np.pi)" ] }, { "cell_type": "code", "execution_count": 84, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "array([[ 0.00000000e+00, 1.63312394e+16],\n", " [-1.63312394e+16, -1.22464680e-16]])" ] }, "execution_count": 84, "metadata": {}, "output_type": "execute_result" } ], "source": [ "np.tan(theta / 360 * 2 * np.pi)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "その他、要素の切り捨て、切り上げ、四捨五入などもベクトルの場合と同様なので省略する。" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## 行列の連結" ] }, { "cell_type": "code", "execution_count": 85, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "array([[1, 2],\n", " [2, 3],\n", " [3, 4]])" ] }, "execution_count": 85, "metadata": {}, "output_type": "execute_result" } ], "source": [ "x = np.array([\n", " [1, 2],\n", " [2, 3],\n", " [3, 4],\n", "])\n", "x" ] }, { "cell_type": "code", "execution_count": 86, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "array([[1.],\n", " [1.],\n", " [1.]])" ] }, "execution_count": 86, "metadata": {}, "output_type": "execute_result" } ], "source": [ "y = np.ones((3, 1))\n", "y" ] }, { "cell_type": "code", "execution_count": 87, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "array([0, 1])" ] }, "execution_count": 87, "metadata": {}, "output_type": "execute_result" } ], "source": [ "z = np.array([0, 1])\n", "z" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "行列・ベクトルを横に(水平に)連結。" ] }, { "cell_type": "code", "execution_count": 88, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "array([[1., 2., 1.],\n", " [2., 3., 1.],\n", " [3., 4., 1.]])" ] }, "execution_count": 88, "metadata": {}, "output_type": "execute_result" } ], "source": [ "np.hstack((x, y))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "行列・ベクトルを縦に(垂直に)連結。" ] }, { "cell_type": "code", "execution_count": 89, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "array([[0, 1],\n", " [1, 2],\n", " [2, 3],\n", " [3, 4]])" ] }, "execution_count": 89, "metadata": {}, "output_type": "execute_result" } ], "source": [ "np.vstack((z, x))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## ビュー" ] }, { "cell_type": "code", "execution_count": 90, "metadata": {}, "outputs": [], "source": [ "x = np.array([\n", " [1, 2, 3, 4],\n", " [2, 3, 4, 5],\n", " [3, 4, 5, 6]\n", "])" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "元の行列・ベクトル(np.ndarray)からスライスで抽出した部分はビュー、すなわち元のオブジェクトへの参照となり、元のオブジェクトとメモリ領域を共有している。以下の例では行列`x`から行ベクトル`y`をビューとして抽出している。" ] }, { "cell_type": "code", "execution_count": 91, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "array([3, 4, 5, 6])" ] }, "execution_count": 91, "metadata": {}, "output_type": "execute_result" } ], "source": [ "y = x[2]\n", "y" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "抽出されたビュー`y`の要素を変更してみる。" ] }, { "cell_type": "code", "execution_count": 92, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "array([0, 4, 5, 6])" ] }, "execution_count": 92, "metadata": {}, "output_type": "execute_result" } ], "source": [ "y[0] = 0\n", "y" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "元の行列`x`の該当する箇所`x[2,0]`も変更されている。" ] }, { "cell_type": "code", "execution_count": 93, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "array([[1, 2, 3, 4],\n", " [2, 3, 4, 5],\n", " [0, 4, 5, 6]])" ] }, "execution_count": 93, "metadata": {}, "output_type": "execute_result" } ], "source": [ "x" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "ビュー`y`の全ての要素を変更する。" ] }, { "cell_type": "code", "execution_count": 94, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "array([0, 0, 0, 0])" ] }, "execution_count": 94, "metadata": {}, "output_type": "execute_result" } ], "source": [ "y[:] = 0\n", "y" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "元の行列`x`の行ベクトル`x[2]`も変更されている。" ] }, { "cell_type": "code", "execution_count": 95, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "array([[1, 2, 3, 4],\n", " [2, 3, 4, 5],\n", " [0, 0, 0, 0]])" ] }, "execution_count": 95, "metadata": {}, "output_type": "execute_result" } ], "source": [ "x" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "なお、ビュー`y`の全体を変更しようとして以下のコードを実行すると、`y`の要素が変更されるのではなく、`y`に`1`が代入されるだけなので混同しないこと。" ] }, { "cell_type": "code", "execution_count": 96, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "1" ] }, "execution_count": 96, "metadata": {}, "output_type": "execute_result" } ], "source": [ "y = 1\n", "y" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "当然、元の行列`x`の要素にも変化がない。" ] }, { "cell_type": "code", "execution_count": 97, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "array([[1, 2, 3, 4],\n", " [2, 3, 4, 5],\n", " [0, 0, 0, 0]])" ] }, "execution_count": 97, "metadata": {}, "output_type": "execute_result" } ], "source": [ "x" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "`x`の部分行列をスライスで取り出した場合も挙動は同じ。" ] }, { "cell_type": "code", "execution_count": 98, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "array([[1, 2],\n", " [2, 3]])" ] }, "execution_count": 98, "metadata": {}, "output_type": "execute_result" } ], "source": [ "y = x[:2,:2]\n", "y" ] }, { "cell_type": "code", "execution_count": 99, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "array([[0, 0],\n", " [0, 0]])" ] }, "execution_count": 99, "metadata": {}, "output_type": "execute_result" } ], "source": [ "y[:] = 0\n", "y" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "`x`全体のビューは[view](https://numpy.org/doc/stable/reference/generated/numpy.ndarray.view.html)メソッドで作成することもできる。" ] }, { "cell_type": "code", "execution_count": 100, "metadata": {}, "outputs": [], "source": [ "y = x.view()" ] }, { "cell_type": "code", "execution_count": 101, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "array([[0, 0, 3, 4],\n", " [0, 0, 4, 5],\n", " [0, 0, 0, 0]])" ] }, "execution_count": 101, "metadata": {}, "output_type": "execute_result" } ], "source": [ "y" ] }, { "cell_type": "code", "execution_count": 102, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "array([[1, 1, 1, 1],\n", " [1, 1, 1, 1],\n", " [1, 1, 1, 1]])" ] }, "execution_count": 102, "metadata": {}, "output_type": "execute_result" } ], "source": [ "y[:] = 1\n", "y" ] }, { "cell_type": "code", "execution_count": 103, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "array([[1, 1, 1, 1],\n", " [1, 1, 1, 1],\n", " [1, 1, 1, 1]])" ] }, "execution_count": 103, "metadata": {}, "output_type": "execute_result" } ], "source": [ "x" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## テンソル" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "スカラー(次元数$0$)やベクトル(次元数$1$)、行列(次元数$2$)を一般化したものをテンソルと呼ぶ。以下のコードは3次元のテンソル$\\mathsf{X}$を定義している。" ] }, { "cell_type": "code", "execution_count": 104, "metadata": {}, "outputs": [], "source": [ "x = np.array([\n", " [\n", " [1, 2, 3],\n", " [2, 3, 4]\n", " ],\n", " [\n", " [3, 4, 5],\n", " [5, 6, 7]\n", " ],\n", "])" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "行列の次元数(軸の数)は3($\\mathsf{X}$は3次元のテンソル)。" ] }, { "cell_type": "code", "execution_count": 105, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "3" ] }, "execution_count": 105, "metadata": {}, "output_type": "execute_result" } ], "source": [ "x.ndim" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "各次元の要素数を表すタプル。$\\mathsf{X}$の1次元目には$2$個、2次元目には$2$個、3次元目には$3$個の要素が格納されている。すなわち、$2 \\times 2 \\times 3$の行列であることを表している。" ] }, { "cell_type": "code", "execution_count": 106, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "(2, 2, 3)" ] }, "execution_count": 106, "metadata": {}, "output_type": "execute_result" } ], "source": [ "x.shape" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "$\\mathsf{X}$の1次元目で1番目の要素(=行列)を取り出したスライス$\\mathsf{X}_{1,:,:}$。" ] }, { "cell_type": "code", "execution_count": 107, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "array([[3, 4, 5],\n", " [5, 6, 7]])" ] }, "execution_count": 107, "metadata": {}, "output_type": "execute_result" } ], "source": [ "x[1,:,:]" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "これは以下のように書くこともできる。" ] }, { "cell_type": "code", "execution_count": 108, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "array([[3, 4, 5],\n", " [5, 6, 7]])" ] }, "execution_count": 108, "metadata": {}, "output_type": "execute_result" } ], "source": [ "x[1,...]" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "$\\mathsf{X}$の3次元目で1番目の要素を取り出したスライス$\\mathsf{X}_{:,:,1}$。" ] }, { "cell_type": "code", "execution_count": 109, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "array([[2, 3],\n", " [4, 6]])" ] }, "execution_count": 109, "metadata": {}, "output_type": "execute_result" } ], "source": [ "x[:,:,1]" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "これは以下のように書くこともできる。" ] }, { "cell_type": "code", "execution_count": 110, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "array([[2, 3],\n", " [4, 6]])" ] }, "execution_count": 110, "metadata": {}, "output_type": "execute_result" } ], "source": [ "x[...,1]" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "行列からテンソルへの変換。" ] }, { "cell_type": "code", "execution_count": 111, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "array([[1, 2],\n", " [3, 4]])" ] }, "execution_count": 111, "metadata": {}, "output_type": "execute_result" } ], "source": [ "x = np.array([\n", " [1, 2],\n", " [3, 4],\n", "])\n", "x" ] }, { "cell_type": "code", "execution_count": 112, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "array([[[1, 2],\n", " [3, 4]]])" ] }, "execution_count": 112, "metadata": {}, "output_type": "execute_result" } ], "source": [ "np.expand_dims(x, 0)" ] }, { "cell_type": "code", "execution_count": 113, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "array([[[1, 2]],\n", "\n", " [[3, 4]]])" ] }, "execution_count": 113, "metadata": {}, "output_type": "execute_result" } ], "source": [ "np.expand_dims(x, 1)" ] }, { "cell_type": "markdown", "metadata": { "tags": [ "remove-cell" ] }, "source": [ "---\n", "\n", "[Python早見帳](https://chokkan.github.io/python/) © Copyright 2020-2022 by [岡崎 直観 (Naoaki Okazaki)](https://www.chokkan.org/). この作品はクリエイティブ・コモンズ 表示 - 非営利 - 改変禁止 4.0 国際 ライセンスの下に提供されています。\"クリエイティブ・コモンズ・ライセンス\"" ] } ], "metadata": { "@context": { "CreativeWork": "http://schema.org/CreativeWork", "Organization": "http://schema.org/Organization", "Person": "http://schema.org/Person", "author": "http://schema.org/author", "copyrightHolder": "http://schema.org/copyrightHolder", "copyrightYear": "http://schema.org/copyrightYear", "license": "http://schema.org/license", "name": "http://schema.org/name", "title": "http://schema.org/name", "url": "http://schema.org/url" }, "@type": "CreativeWork", "author": [ { "@type": "Person", "name": "Naoaki Okazaki", "url": "https://www.chokkan.org/" } ], "copyrightHolder": [ { "@type": "Person", "name": "Naoaki Okazaki", "url": "https://www.chokkan.org/" } ], "copyrightYear": 2022, "kernelspec": { "display_name": "Python 3 (ipykernel)", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.8.10" }, "license": "https://creativecommons.org/licenses/by-nc-nd/4.0/deed.ja", "title": "Python早見帳" }, "nbformat": 4, "nbformat_minor": 4 }