{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# NumPy"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<div name=\"html-admonition\" style=\"font-size: 0.8em\">\n",
    "<input type=\"button\" onclick=\"location.href='https://translate.google.com/translate?hl=&sl=ja&tl=en&u='+window.location;\" value=\"Google translation\" style=\"color:#ffffff;background-color:#008080; height:25px\" onmouseover=\"this.style.background='#99ccff'\" onmouseout=\"this.style.background='#008080'\"/> in English or the language of your choice.\n",
    "</div><br>"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 警告メッセージを非表示\n",
    "import warnings\n",
    "warnings.filterwarnings(\"ignore\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "heading_collapsed": true
   },
   "source": [
    "## array"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "hidden": true
   },
   "source": [
    "このパッケージは,数値計算をする上で重要な役割を果たし,特に,行列計算に威力を発揮する。`NumPy`は「ナンパイ」と読む。\n",
    "\n",
    "慣例として`np`として読み込む。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "hidden": true
   },
   "outputs": [],
   "source": [
    "import numpy as np"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "hidden": true
   },
   "source": [
    "基本となる関数が`np.array()`であり,次のコードでは1次元配列を作る。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "hidden": true
   },
   "outputs": [],
   "source": [
    "arr = np.array([10, 20, 30, 40, 50])\n",
    "arr"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "hidden": true
   },
   "outputs": [],
   "source": [
    "type(arr)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "hidden": true
   },
   "source": [
    "次に2次元配列、即ち、行列を作る。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "hidden": true
   },
   "outputs": [],
   "source": [
    "mat = np.array([[1, 2, 3, 4], [5, 6, 7, 8], [9, 10, 11, 12], [13, 14, 15, 16]])\n",
    "mat"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "hidden": true
   },
   "outputs": [],
   "source": [
    "print(type(arr))\n",
    "print(type(mat))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "hidden": true
   },
   "source": [
    "`arr`と`mat`は`NumPy`の`ndarray`(`n`次元`array`)というデータ型(クラス)である。`[]`に囲まれた数字が並んでいるがリストとではない。従って,要素を抽出して直接リストとして扱うことはできない。そのためにはリストへの変換が必要になるが,その方法については後述する。"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "heading_collapsed": true
   },
   "source": [
    "## 1次元配列:要素の抽出"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "hidden": true
   },
   "source": [
    "`arr`の要素を抽出するには要素のインデックスを使う。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "hidden": true
   },
   "outputs": [],
   "source": [
    "arr[1]"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "hidden": true
   },
   "source": [
    "複数の要素を抽出するにはインデックスをリストとして使う。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "hidden": true
   },
   "outputs": [],
   "source": [
    "arr[[0,1,3]]"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "hidden": true
   },
   "source": [
    "要素を連続で抽出するスライシング(slicing)も使うことができる。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "hidden": true
   },
   "outputs": [],
   "source": [
    "arr[1:4]"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "heading_collapsed": true
   },
   "source": [
    "## 2次元配列:要素の抽出"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "hidden": true
   },
   "source": [
    "第$i$行目の第$j$列目要素にアクセスするためには`mat[i,j]`と書く。`[,]`の`,`を挟んで左が行を表し,右が列を示す。\n",
    "```\n",
    "[行のインデックス,列のインデックス]\n",
    "```\n",
    "\n",
    "コードはキーストロークが少なく,簡単なものが良いと考えられている。一方で,`Python`は初心者に易しい言語だと言われるが,それでも関数・メソッドの数は膨大で,そのオプションとの組み合わせを考えるとまさしく「無数」にあると言っても過言ではない。そのため初心者にとって関数の使い方やオプションの書き方を間違う可能性は小さくない。さらに,自分が書いたコードを数週間・数ヶ月後に読み直すと,何をしようとしているのか分からないという状況が生じることもある。従って,初心者にとっては以下の点が非常に重要になる。\n",
    "\n",
    "* 間違いにくいコードの書き方を覚える。\n",
    "* 高い可読性を意識したコードの書き方を覚える。\n",
    "\n",
    "このスタンスに基づいて以下のルールに従って説明する。\n",
    "\n",
    "1. `[,]`内の`,`を省略可能な場合であっても省略しない。\n",
    "2. `[,]`内の`,`の左または右を省略できる場合であっても省略しない。\n",
    "\n",
    "行または列を連続選択する(slicing)場合を考えよう。以下で説明するように`:`を使うが\n",
    "```\n",
    "start:end\n",
    "```\n",
    "となる。ここで`start`とは選択する要素の最初インデックスであり,`end`は選択する最後の要素の次のインデックスである(リストの場合と同じ)。上のルールに従うと,\n",
    "\n",
    "* `,`の左または右が`:`のみの場合,「全て」という意味になる。\n",
    "* `:`の左を省略すると「最初から」という意味になる。\n",
    "* `:`の右を省略すると「最後まで」という意味になる。\n",
    "\n",
    "これを読むだけでは分かりにくいと思うので,以下の例に目を通してもう一度この箇所の説明を読んむことを推奨する。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "hidden": true
   },
   "outputs": [],
   "source": [
    "mat[0,1]"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "hidden": true
   },
   "source": [
    "第$i$行の抽出は`mat[i,:]`で可能である。`:`は「列の全て」という意味になる。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "hidden": true
   },
   "outputs": [],
   "source": [
    "r0 = mat[0,:]\n",
    "r0"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "hidden": true
   },
   "source": [
    "抽出した行は上で説明した1次元配列なのでインデックスやスライシングを使って要素にアクセスすることができる。"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "hidden": true
   },
   "source": [
    "複数の行の抽出は次の方法で可能である。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "hidden": true
   },
   "outputs": [],
   "source": [
    "mat[1:3,:]"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "hidden": true
   },
   "source": [
    "第3行目は含まれないことに注意しよう。リストの要素の取り出し方と同じように`:`の右のインデックスの行は含まれない。\n",
    "\n",
    "**(注意)**\n",
    "\n",
    "`,:`を省略して`mat[1:3]`と書いてもエラーは発生せず同じ結果が返されるが,`,:`があることにより,行を抽出しており列は全て選択されていることが明示的になる。\n",
    "\n",
    "\n",
    "第$i$ 列目を抽出したい場合は次のコードになる。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "hidden": true
   },
   "outputs": [],
   "source": [
    "mat[:, 1]"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "hidden": true
   },
   "source": [
    "複数列の抽出は以下のようにする。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "hidden": true
   },
   "outputs": [],
   "source": [
    "mat[:, 1:3]"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "hidden": true
   },
   "source": [
    "`:`の役割を考えると以下は`mat`自体である。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "hidden": true
   },
   "outputs": [],
   "source": [
    "mat[:,:]"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "heading_collapsed": true
   },
   "source": [
    "## 行列計算"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "hidden": true
   },
   "source": [
    "まず2つの行列(2次元配列`array`)を作成する。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "hidden": true
   },
   "outputs": [],
   "source": [
    "m1 = np.array([[1, 1], [1, 1]])\n",
    "m1"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "hidden": true
   },
   "outputs": [],
   "source": [
    "m2 = np.array([[2, 2], [2, 2]])\n",
    "m2"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "hidden": true
   },
   "source": [
    "**行列の和**\n",
    "\n",
    "要素ごとの和となる。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "hidden": true
   },
   "outputs": [],
   "source": [
    "m2 + m1"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "hidden": true
   },
   "source": [
    "**行列の差**\n",
    "\n",
    "要素ごとの差となる。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "hidden": true
   },
   "outputs": [],
   "source": [
    "m2 - m1"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "hidden": true
   },
   "source": [
    "**行列のスカラー積**\n",
    "\n",
    "与えられた定数とそれぞれの要素の積となる。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "hidden": true
   },
   "outputs": [],
   "source": [
    "10 * m1"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "hidden": true
   },
   "outputs": [],
   "source": [
    "m1/2  # 1/2をかけるのと同じ"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "hidden": true
   },
   "source": [
    "**行列の積:バージョン1**\n",
    "\n",
    "`*`を使うと要素どうしの積となる。数学で学んだ行列の式とは異なるので注意すること。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "hidden": true
   },
   "outputs": [],
   "source": [
    "m1*m2"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "hidden": true
   },
   "source": [
    "**行列の積:バージョン2**\n",
    "\n",
    "`@`を使うと数学で学ぶ行列の積となる。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "hidden": true
   },
   "outputs": [],
   "source": [
    "m1@m2"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "hidden": true
   },
   "source": [
    "`numpy`の関数`dot()`は`@`と同じとなる。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "hidden": true
   },
   "outputs": [],
   "source": [
    "np.dot(m1,m2)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "hidden": true
   },
   "source": [
    "**転置行列**\n",
    "\n",
    "数学で学ぶ転置行列と同じ。`m3`を使って説明する。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "hidden": true
   },
   "outputs": [],
   "source": [
    "m3 = np.array([[1,2,3],[4,5,6]])\n",
    "m3"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "hidden": true
   },
   "source": [
    "`m3`のメソッド`transpose()`を使う。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "hidden": true
   },
   "outputs": [],
   "source": [
    "m3.transpose()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "hidden": true
   },
   "source": [
    "`.transpose()`の省略形として`.T`を使うこともできる。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "hidden": true
   },
   "outputs": [],
   "source": [
    "m3.T"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "hidden": true
   },
   "source": [
    "**逆行列**\n",
    "\n",
    "数学で学ぶ逆行列である。`m4`を使い説明する。逆行列を計算するために`numpy`の`linalg`(linear algebra, 線形代数)というサブパッケージの中にある`inv`という関数を読み込む。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "hidden": true
   },
   "outputs": [],
   "source": [
    "from numpy.linalg import inv\n",
    "\n",
    "m4 = np.array([[1,2],[3,4]])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "hidden": true
   },
   "outputs": [],
   "source": [
    "inv(m4)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "heading_collapsed": true
   },
   "source": [
    "## NumPy使用時によく使う属性とメソッド"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "hidden": true
   },
   "source": [
    "以前も説明したが、メソッドとはオブジェクト特有の関数であり、オブジェクトの属性の1つである。もう1つの属性の種類にデータ属性(例えば,行数)がある。あるオブジェクトにどのような属性があるかは関数`dir()`を使うことにより確認できる。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "hidden": true,
    "tags": [
     "output_scroll"
    ]
   },
   "outputs": [],
   "source": [
    "dir(m3)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "hidden": true
   },
   "source": [
    "このリストの中に`transpose()`や`T`があるのが確認できる。この中でよく使うのが`shape`であり,行と列の数を確認する場合に有用なデータ属性である。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "hidden": true
   },
   "outputs": [],
   "source": [
    "m3.shape"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "hidden": true
   },
   "source": [
    "データ属性には`()`がない。一方,メソッド属性は`()`が必要となる。言い換えると,メソッドの`()`は「実行する」ということを意味する。\n",
    "\n",
    "次に,抽出した行または列をリストに変換するメソッドについて説明する。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "hidden": true
   },
   "outputs": [],
   "source": [
    "r0 = mat[0,:]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "hidden": true
   },
   "outputs": [],
   "source": [
    "type(r0)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "hidden": true
   },
   "source": [
    "`r0`のデータ型は`NumPy`の`ndarray`である。これをリストに変換するために`tolist()`というメソッドを使う。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "hidden": true
   },
   "outputs": [],
   "source": [
    "r0_list = r0.tolist()\n",
    "\n",
    "r0_list"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "hidden": true
   },
   "outputs": [],
   "source": [
    "type(r0_list)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "heading_collapsed": true
   },
   "source": [
    "## よく使うNumPy関数"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "hidden": true
   },
   "source": [
    "**ルート $\\left(\\sqrt x\\right)$**"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "hidden": true
   },
   "outputs": [],
   "source": [
    "np.sqrt(4)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "hidden": true
   },
   "source": [
    "`sqrt`は square root の略。"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "hidden": true
   },
   "source": [
    "**底が$e$の指数関数($e^x$)**"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "hidden": true
   },
   "outputs": [],
   "source": [
    "np.exp(10)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "hidden": true
   },
   "source": [
    "`exp`は exponentiation の略"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "hidden": true
   },
   "source": [
    "**自然対数($\\log_ex$または$\\ln x$)**"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "hidden": true
   },
   "outputs": [],
   "source": [
    "np.log(10)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "hidden": true
   },
   "source": [
    "**`0`が$N$個の`array`を作る。**\n",
    "```\n",
    "np.zeros(N)\n",
    "```"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "hidden": true
   },
   "outputs": [],
   "source": [
    "np.zeros(10)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "hidden": true
   },
   "source": [
    "**`1`(float)が$N$個の`array`を作る。**\n",
    "```\n",
    "np.ones(N)\n",
    "```"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "hidden": true
   },
   "outputs": [],
   "source": [
    "np.ones(10)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "hidden": true
   },
   "source": [
    "**$a$から$b$までの区間を等間隔に割った$N$個の数字を返す。**\n",
    "```\n",
    "np.linspace(a,b,N)\n",
    "```"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "hidden": true
   },
   "outputs": [],
   "source": [
    "np.linspace(0,1,5)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "hidden": true
   },
   "source": [
    "**$a$から$b$までの区間で$m$ステップずつ増加し等間隔に割った数字を返す($b$は含まない)。**\n",
    "\n",
    "```\n",
    "np.arange(a,b,m)\n",
    "```\n",
    "`m = 1`の場合,組み込み関数の`range(a,b)`と同じ数字を生成するが,返り値が`array`であることが異なる。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "hidden": true
   },
   "outputs": [],
   "source": [
    "np.arange(5,10,0.5)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "hidden": true
   },
   "source": [
    "**標本平均**\n",
    "\n",
    "`x`が数字の`array`やリストの場合\n",
    "\n",
    "`np.mean(x)`$=\\bar{x}=\\frac{1}{n}\\sum_{i=1}^{n}x_i$"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "hidden": true
   },
   "outputs": [],
   "source": [
    "xx = [1,2,3,4,5,6]\n",
    "np.mean(xx)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "hidden": true
   },
   "source": [
    "**標本中央値**\n",
    "\n",
    "`x`が数字の`array`やリストの場合\n",
    "\n",
    "`np.median(x)`"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "hidden": true
   },
   "outputs": [],
   "source": [
    "np.median(xx)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "hidden": true
   },
   "source": [
    "**標本分散**\n",
    "\n",
    "`x`が数字の`array`やリストの場合\n",
    "\n",
    "`np.var(x, ddof=0)`$=s_x^2=\\dfrac{1}{n-\\text{ddof}}\\sum_{i=1}^n\\left(x_i-\\bar{x}\\right)^2$(`ddof=0`がデフォルト)\n",
    "\n",
    "(注意)計量経済学で習う分散の不偏推定量は`ddof=1`が必要!"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "hidden": true
   },
   "outputs": [],
   "source": [
    "np.var(xx,ddof=1)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "hidden": true
   },
   "source": [
    "**標本標準偏差**\n",
    "\n",
    "`x`が数字の`array`やリストの場合\n",
    "\n",
    "`np.std(x, ddof=0)`$=s_x=\\sqrt{s_x^2}$  (`ddof=0`がデフォルト)\n",
    "\n",
    "(注意)標本標準偏差の場合,必ずしも`ddof=1`により不偏推定量とはならないが,通常`ddof=1`を用いる。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "hidden": true
   },
   "outputs": [],
   "source": [
    "np.std(xx,ddof=1)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "hidden": true
   },
   "source": [
    "**標本共分散**\n",
    "\n",
    "2次元以上の`array`やリストの場合\n",
    "\n",
    "`np.cov(xy, ddof=0)`$=c_{xy}=\\dfrac{1}{n-\\text{ddof}}\\sum_{i=1}^n(x_i-\\bar{x})(y_i-\\bar{y})$(`ddof=0`がデフォルト)\n",
    "\n",
    "(注意1)計量経済学で習う分散の不偏推定量は`ddof=1`が必要!\n",
    "\n",
    "下の計算結果\n",
    "\n",
    "* $c_{xy}=-0.6$\n",
    "* $s_x^2=3.5$  (\\[1,2,3,4,5,6\\]の分散)\n",
    "* $s_y^2=4.4$  (\\[1,6,2,5,3,1\\]の分散)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "hidden": true
   },
   "outputs": [],
   "source": [
    "x = [1,2,3,4,5,6]\n",
    "y = [1,6,2,5,3,1]\n",
    "\n",
    "cov_xy = np.cov([x,y],ddof=1)\n",
    "cov_xy"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "hidden": true,
    "tags": [
     "remove-cell"
    ]
   },
   "outputs": [],
   "source": [
    "from myst_nb import glue\n",
    "varx = cov_xy[0,0]\n",
    "vary = cov_xy[1,1]\n",
    "covxy = cov_xy[0,1]\n",
    "glue('varx', varx, display=False)\n",
    "glue('vary', vary, display=False)\n",
    "glue('covxy', covxy, display=False)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "hidden": true
   },
   "source": [
    "ここでそれぞれの数字は次を表している。\n",
    "* {glue:text}`covxy:.1f`:`x`と`y`の共分散であり,次のように値を抽出できる。\n",
    "    ```\n",
    "    `cov_xy[0,1]` もしくは `cov_xy[1,0]`\n",
    "    ```\n",
    "* {glue:text}`varx`:`x`の分散であり,次のように値を抽出できる。\n",
    "    ```\n",
    "    `cov_xy[0,0]`\n",
    "    ```\n",
    "* {glue:text}`vary`:`y`の分散であり,次のように値を抽出できる。\n",
    "    ```\n",
    "    `cov_xy[1,1]`\n",
    "    ```"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "hidden": true
   },
   "source": [
    "**標本相関係数**\n",
    "\n",
    "2次元以上の`array`やリストの場合\n",
    "\n",
    "`np.corrcoef(xy)`$=r_{xy}=\\dfrac{c_{xy}}{s_x\\cdot s_y}$\n",
    "\n",
    "(注意)`ddof`の影響はない。\n",
    "\n",
    "下の計算結果\n",
    "* $r_{xy}=-0.152...$\n",
    "* $r_{xx}=r_{yy}=1$"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "hidden": true
   },
   "outputs": [],
   "source": [
    "corr_xy = np.corrcoef([x,y])\n",
    "corr_xy"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "hidden": true,
    "tags": [
     "remove-cell"
    ]
   },
   "outputs": [],
   "source": [
    "from myst_nb import glue\n",
    "corrx = corr_xy[0,0]\n",
    "corry = corr_xy[1,1]\n",
    "corrxy = corr_xy[0,1]\n",
    "glue('corrx', corrx, display=False)\n",
    "glue('corry', corry, display=False)\n",
    "glue('corrxy', corrxy, display=False)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "hidden": true
   },
   "source": [
    "ここでそれぞれの数字は次を表している。\n",
    "* {glue:text}`corrxy:.8f`:`x`と`y`の相関係数であり,次のように値を抽出できる。\n",
    "    ```\n",
    "    `corr_xy[0,1]` もしくは `corr_xy[1,0]`\n",
    "    ```\n",
    "* {glue:text}`corrx`:`x`と`x`の相関関係であり,次のように値を抽出できる。\n",
    "    ```\n",
    "    `corr_xy[0,0]`\n",
    "    ```\n",
    "* {glue:text}`corry`:`y`と`y`の相関係数であり,次のように値を抽出できる。\n",
    "    ```\n",
    "    `corr_xy[1,1]`\n",
    "    ```"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "heading_collapsed": true
   },
   "source": [
    "## array vs list"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "hidden": true
   },
   "source": [
    "ここでは`list`と`NumPy`の`array`の重要な違いについて説明する。\n",
    "次のリストのそれぞれの要素に`10`を足したいとしよう。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "hidden": true
   },
   "outputs": [],
   "source": [
    "list0 = [1.0, 2.0, 3.0, 4.0, 5.0]"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "hidden": true
   },
   "source": [
    "`for`ループを使うと次のようになる。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "hidden": true
   },
   "outputs": [],
   "source": [
    "list1 = []\n",
    "for i in list0:\n",
    "    list1.append(i + 10)\n",
    "\n",
    "list1"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "hidden": true
   },
   "source": [
    "もう1つの方法として内包標記(list comprehension)がある。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "hidden": true
   },
   "outputs": [],
   "source": [
    "list2 = [i + 10 for i in list0]\n",
    "list2"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "hidden": true
   },
   "source": [
    "どちらの方法を使ったとしても複雑さが残る。また次のコードでは`10`を最後に追加するだけである。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "hidden": true
   },
   "outputs": [],
   "source": [
    "list0 + [10]"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "hidden": true
   },
   "source": [
    "より簡単なコードで実行できれば良いが,以下のコードではエラーが発生する。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "hidden": true,
    "tags": [
     "raises-exception"
    ]
   },
   "outputs": [],
   "source": [
    "list0 + 10"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "hidden": true
   },
   "source": [
    "---\n",
    "これを実現するのが`NumPy`の`array`である。\n",
    "\n",
    "まず`array`を作成する。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "hidden": true
   },
   "outputs": [],
   "source": [
    "arr0 = np.array(list0)\n",
    "arr0"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "hidden": true
   },
   "outputs": [],
   "source": [
    "arr0 + 10"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "hidden": true
   },
   "source": [
    "この機能はベクトル演算(Vectorization)と呼ばれ、ループを使わずに個々の要素に直接働きかけ計算している。上記のコードは次の計算を行っている。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "hidden": true
   },
   "outputs": [],
   "source": [
    "arr0 + np.array([10]*5)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "hidden": true
   },
   "source": [
    "裏で`arr0`の長さに合わせて`10`を「拡張」し計算している。この機能により、より高速な計算が可能となるばかりか、より短いコードでそれを実現できる。`+`, `-`, `*`, `**` や他の関数にも同様に使うことができる。以下で例を挙げる。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "hidden": true
   },
   "outputs": [],
   "source": [
    "arr0 - 5"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "hidden": true
   },
   "outputs": [],
   "source": [
    "arr0 * 10  "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "hidden": true
   },
   "outputs": [],
   "source": [
    "arr0 ** 2"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "hidden": true
   },
   "outputs": [],
   "source": [
    "np.sqrt(arr0)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "hidden": true
   },
   "outputs": [],
   "source": [
    "np.log(arr0)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "hidden": true
   },
   "source": [
    "次の計算も可能である。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "hidden": true
   },
   "outputs": [],
   "source": [
    "y = arr0 * 2 + np.sqrt(arr0) + 10\n",
    "y"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "hidden": true
   },
   "source": [
    "この機能は`NumPy`の行列でも有効である。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "hidden": true
   },
   "outputs": [],
   "source": [
    "mat0 = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]])\n",
    "mat0"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "hidden": true
   },
   "outputs": [],
   "source": [
    "mat0 * 10"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "hidden": true
   },
   "outputs": [],
   "source": [
    "np.sqrt(mat0)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "hidden": true
   },
   "outputs": [],
   "source": [
    "np.log(mat0)"
   ]
  }
 ],
 "metadata": {
  "celltoolbar": "Tags",
  "kernel_info": {
   "name": "python3"
  },
  "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.11.5"
  },
  "nteract": {
   "version": "0.15.0"
  },
  "toc": {
   "base_numbering": 1,
   "nav_menu": {},
   "number_sections": true,
   "sideBar": true,
   "skip_h1_title": false,
   "title_cell": "Table of Contents",
   "title_sidebar": "Contents",
   "toc_cell": false,
   "toc_position": {},
   "toc_section_display": true,
   "toc_window_display": false
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}