{
 "cells": [
  {
   "cell_type": "markdown",
   "id": "intro",
   "metadata": {},
   "source": [
    "# 01　NumPyで数をまとめる\n",
    "\n",
    "FUJIMOTO LAB 深層学習コース。Web教材の図と説明を読んでから実行してください。Pythonの計算はColabの実行環境で行います。\n",
    "\n",
    "**この回の目標**：配列の形と要素ごとの計算を説明できる\n",
    "\n",
    "このノートブックは小さな合成データを使用し、元の教材の固定Driveパスや動画を必要としません。"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "predict",
   "metadata": {},
   "source": [
    "## 1　まず予想する\n",
    "\n",
    "コードを実行する前に、表示される値や形を予想してください。"
   ]
  },
  {
   "cell_type": "code",
   "id": "demo-one",
   "metadata": {},
   "source": [
    "import numpy as np\n",
    "weights = np.array([100, 120, 90])\n",
    "print(weights.shape)\n",
    "print(weights + 10)"
   ],
   "execution_count": null,
   "outputs": []
  },
  {
   "cell_type": "markdown",
   "id": "explain-one",
   "metadata": {},
   "source": [
    "**確かめ方**：NumPyが10を各要素へ適用する仕組みをブロードキャストと呼びます。元のweights自体は変わりません。"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "part-two",
   "metadata": {},
   "source": [
    "## 2　2行3列の表に、3個の数を足そう\n",
    "\n",
    "計算前の表は2行3列です。加える[10, 20, 30]は、横に並ぶ3列それぞれへ対応する3個の数です。どの数とどの数を足すか、結果を見る前に予想してみよう。"
   ]
  },
  {
   "cell_type": "code",
   "id": "demo-two",
   "metadata": {},
   "source": [
    "table = np.array([[1, 2, 3], [4, 5, 6]])\n",
    "bonus = np.array([10, 20, 30])\n",
    "print('元の表', table.shape)\n",
    "print(table)\n",
    "print('加える数', bonus.shape, bonus)\n",
    "print('結果')\n",
    "print(table + bonus)"
   ],
   "execution_count": null,
   "outputs": []
  },
  {
   "cell_type": "markdown",
   "id": "explain-two",
   "metadata": {},
   "source": [
    "**結果を読む**：結果は、元の表の各行に[10, 20, 30]を足した新しい表です。1行目は1+10、2+20、3+30。2行目は4+10、5+20、6+30になります。元のtableは変わりません。"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "experiment",
   "metadata": {},
   "source": [
    "## 3　値を変えて比べる\n",
    "\n",
    "次のセルでは、表示される値や条件を変えて、何が結果を決めるかを確かめます。長くかかる実験は、少数の合成データで行います。"
   ]
  },
  {
   "cell_type": "code",
   "id": "lab",
   "metadata": {},
   "source": [
    "# 各列へ足す数を変え、結果を予想してから実行しよう\n",
    "my_bonus = np.array([1, 10, 100])\n",
    "print('予想した結果と比べる:\\n', table + my_bonus)\n",
    "print('元の表はそのまま:\\n', table)\n"
   ],
   "execution_count": null,
   "outputs": []
  },
  {
   "cell_type": "markdown",
   "id": "extra-guide-1",
   "metadata": {},
   "source": [
    "## 追加実習 1　1マスずつ足してみる\n",
    "\n",
    "元の表は2行3列、加える数は3個の1次元配列です。同じ列の数を、両方の行に加えます。\n",
    "\n",
    "**実行前に予想**：何が変わり、何が変わらないでしょうか。"
   ]
  },
  {
   "cell_type": "code",
   "id": "extra-code-1",
   "metadata": {},
   "source": [
    "for row_number, row in enumerate(table, start=1):\n",
    "    print(f'{row_number}行目: {row} + {bonus} = {row + bonus}')\n",
    "print('元の表は変わらない:', table)\n"
   ],
   "execution_count": null,
   "outputs": []
  },
  {
   "cell_type": "markdown",
   "id": "extra-reflect-1",
   "metadata": {},
   "source": [
    "**確認**：予想と違った点を一つ書き、値を一つ変えて再実行してください。"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "extra-guide-2",
   "metadata": {},
   "source": [
    "## 追加実習 2　3通りの足し方を比べる\n",
    "\n",
    "1個の数を全マスへ、3個の数を各列へ、縦に並ぶ2個の数を各行へ。shapeも並べて確認しましょう。\n",
    "\n",
    "**実行前に予想**：何が変わり、何が変わらないでしょうか。"
   ]
  },
  {
   "cell_type": "code",
   "id": "extra-code-2",
   "metadata": {},
   "source": [
    "row_bonus = np.array([[10], [20]])\n",
    "print('元の表の形', table.shape)\n",
    "print('各列へ加える数の形', bonus.shape)\n",
    "print('各行へ加える数の形', row_bonus.shape)\n",
    "print('全マスへ10を足す:\\n', table + 10)\n",
    "print('各列へ足す:\\n', table + bonus)\n",
    "print('各行へ足す:\\n', table + row_bonus)\n"
   ],
   "execution_count": null,
   "outputs": []
  },
  {
   "cell_type": "markdown",
   "id": "extra-reflect-2",
   "metadata": {},
   "source": [
    "**確認**：予想と違った点を一つ書き、値を一つ変えて再実行してください。"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "extra-guide-3",
   "metadata": {},
   "source": [
    "## 追加実習 3　形が合わないときはどうなる？\n",
    "\n",
    "横3列の表へ、横2個の1次元配列は対応しません。一方、縦2行・横1列の配列は行ごとに対応できます。\n",
    "\n",
    "**実行前に予想**：何が変わり、何が変わらないでしょうか。"
   ]
  },
  {
   "cell_type": "code",
   "id": "extra-code-3",
   "metadata": {},
   "source": [
    "wrong_bonus = np.array([10, 20])\n",
    "try:\n",
    "    print(table + wrong_bonus)\n",
    "except ValueError as error:\n",
    "    print('形が合わない:', type(error).__name__)\n",
    "print('縦に並べた2個なら計算できる:\\n', table + wrong_bonus[:, None])\n"
   ],
   "execution_count": null,
   "outputs": []
  },
  {
   "cell_type": "markdown",
   "id": "extra-reflect-3",
   "metadata": {},
   "source": [
    "**確認**：予想と違った点を一つ書き、値を一つ変えて再実行してください。"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "extra-guide-4",
   "metadata": {},
   "source": [
    "## 追加実習 4　平均を取る方向\n",
    "\n",
    "axis=0は各列、axis=1は各行をまとめる方向です。先に結果の個数を予想しましょう。\n",
    "\n",
    "**実行前に予想**：何が変わり、何が変わらないでしょうか。"
   ]
  },
  {
   "cell_type": "code",
   "id": "extra-code-4",
   "metadata": {},
   "source": [
    "print('列ごとの平均 (3個):', table.mean(axis=0))\n",
    "print('行ごとの平均 (2個):', table.mean(axis=1))\n"
   ],
   "execution_count": null,
   "outputs": []
  },
  {
   "cell_type": "markdown",
   "id": "extra-reflect-4",
   "metadata": {},
   "source": [
    "**確認**：予想と違った点を一つ書き、値を一つ変えて再実行してください。"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "extra-guide-5",
   "metadata": {},
   "source": [
    "## 追加実習 5　画像の画素も数の表\n",
    "\n",
    "6個の画素に明るさ40を加えます。画素は通常0〜255なので、np.clipで255を超えないようにします。\n",
    "\n",
    "**実行前に予想**：何が変わり、何が変わらないでしょうか。"
   ]
  },
  {
   "cell_type": "code",
   "id": "extra-code-5",
   "metadata": {},
   "source": [
    "import matplotlib.pyplot as plt\n",
    "pixels = np.array([[30, 80, 130], [180, 220, 250]], dtype=np.uint8)\n",
    "brighter = np.clip(pixels.astype(int) + 40, 0, 255).astype(np.uint8)\n",
    "print('元の画素:\\n', pixels)\n",
    "print('明るくした画素:\\n', brighter)\n",
    "fig, axes = plt.subplots(1, 2, figsize=(7, 2.5))\n",
    "for ax, data, title in zip(axes, [pixels, brighter], ['Before', 'After']):\n",
    "    ax.imshow(data, cmap='gray', vmin=0, vmax=255)\n",
    "    ax.set_title(title)\n",
    "    ax.axis('off')\n",
    "plt.show()\n"
   ],
   "execution_count": null,
   "outputs": []
  },
  {
   "cell_type": "markdown",
   "id": "extra-reflect-5",
   "metadata": {},
   "source": [
    "**確認**：予想と違った点を一つ書き、値を一つ変えて再実行してください。"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "reflection",
   "metadata": {},
   "source": [
    "## 自分の言葉で答えよう\n",
    "\n",
    "2行目[4, 5, 6]へ[10, 20, 30]を足すと？\n",
    "\n",
    "- まず予想を書く\n",
    "- コードのどの行が答えを決めるか指す\n",
    "- 条件や値を1つ変えて、予想と実行結果を比べる\n",
    "\n",
    "**ヒント**：同じ位置の数を足します。4+10、5+20、6+30です。"
   ]
  }
 ],
 "metadata": {
  "colab": {
   "name": "01-arrays.ipynb",
   "provenance": []
  },
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "name": "python"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
