{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "source": [
    "## Uczenie maszynowe 2020/2021 – laboratoria\n",
    "### 3 marca 2021\n",
    "# 1. Python – listy składane, indeksowanie, biblioteka _NumPy_"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Listy składane (*List comprehension*)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 52,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[1, 4, 9, 16, 25, 36, 49, 64, 81, 100]\n"
     ]
    }
   ],
   "source": [
    "lista = []\n",
    "for x in range(1, 11):\n",
    "    lista.append(x ** 2)\n",
    "    \n",
    "print(lista)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 53,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[1, 4, 9, 16, 25, 36, 49, 64, 81, 100]\n"
     ]
    }
   ],
   "source": [
    "lista = [x ** 2 for x in range(1, 11)]\n",
    "print(lista)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Przypuśćmy, że mamy dane zdanie i chcemy utworzyć listę, która będzie zawierać długości kolejnych wyrazów tego zdania. Możemy to zrobić w następujący sposób:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 54,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[4, 16, 36, 64, 100]\n"
     ]
    }
   ],
   "source": [
    "lista = []\n",
    "for i in range(1, 11):\n",
    "    if i % 2 == 0:\n",
    "        lista.append(i ** 2)\n",
    "    \n",
    "print(lista)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 55,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[4, 16, 36, 64, 100]\n"
     ]
    }
   ],
   "source": [
    "lista = [i ** 2 for i in range(1, 11) if i % 2 == 0]\n",
    "print(lista)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 56,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]"
      ]
     },
     "execution_count": 56,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "list(range(1, 11))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 57,
   "metadata": {
    "scrolled": true
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "tracz tarł tarcicę tak takt w takt jak takt w takt tarcicę tartak tarł\n"
     ]
    }
   ],
   "source": [
    "zdanie = 'tracz tarł tarcicę tak takt w takt jak takt w takt tarcicę tartak tarł'\n",
    "print(zdanie)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 58,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "['tracz', 'tarł', 'tarcicę', 'tak', 'takt', 'w', 'takt', 'jak', 'takt', 'w', 'takt', 'tarcicę', 'tartak', 'tarł']\n"
     ]
    }
   ],
   "source": [
    "wyrazy = zdanie.split()\n",
    "print(wyrazy)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 59,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[5, 4, 7, 3, 4, 1, 4, 3, 4, 1, 4, 7, 6, 4]\n"
     ]
    }
   ],
   "source": [
    "dlugosci_wyrazow = []\n",
    "for wyraz in wyrazy:\n",
    "    dlugosci_wyrazow.append(len(wyraz))\n",
    "    \n",
    "print(dlugosci_wyrazow)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 60,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[5, 4, 7, 3, 4, 1, 4, 3, 4, 1, 4, 7, 6, 4]\n"
     ]
    }
   ],
   "source": [
    "dlugosci_wyrazow = [len(wyraz) for wyraz in wyrazy]\n",
    "print(dlugosci_wyrazow)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 61,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[5, 4, 7, 3, 4, 1, 4, 3, 4, 1, 4, 7, 6, 4]\n"
     ]
    }
   ],
   "source": [
    "zdanie = 'tracz tarł tarcicę tak takt w takt jak takt w takt tarcicę tartak tarł'\n",
    "wyrazy = zdanie.split()\n",
    "dlugosci_wyrazow = []\n",
    "for wyraz in wyrazy:\n",
    "    dlugosci_wyrazow.append(len(wyraz))\n",
    "    \n",
    "print(dlugosci_wyrazow)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Możemy to też zrobić bardziej „pythonicznie”, przy użyciu list składanych:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 62,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[5, 4, 7, 3, 4, 1, 4, 3, 4, 1, 4, 7, 6, 4]\n"
     ]
    }
   ],
   "source": [
    "zdanie = 'tracz tarł tarcicę tak takt w takt jak takt w takt tarcicę tartak tarł'\n",
    "dlugosci_wyrazow = [len(wyraz) for wyraz in zdanie.split()]\n",
    "\n",
    "print(dlugosci_wyrazow)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Jeżeli chcemy, żeby był sprawdzany dodatkowy warunek, np. chcemy pomijać wyraz „takt”, to wciąż możemy użyć list składanych:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 63,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[5, 4, 7, 3, 1, 3, 1, 7, 6, 4]\n"
     ]
    }
   ],
   "source": [
    "zdanie = 'tracz tarł tarcicę tak takt w takt jak takt w takt tarcicę tartak tarł'\n",
    "wyrazy = zdanie.split()\n",
    "dlugosci_wyrazow = [len(wyraz) for wyraz in wyrazy if wyraz != 'takt']\n",
    "print(dlugosci_wyrazow)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Indeksowanie"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Wszystkie listy i krotki w Pythonie, w tym łańcuchy (które trakowane są jak krotki znaków), są indeksowane od 0:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 64,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "a\n",
      "e\n"
     ]
    }
   ],
   "source": [
    "napis = 'abcde'\n",
    "print(napis[0])  # 'a'\n",
    "print(napis[4])  # 'e'"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Indeksy możemy liczyć również „od końca”:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 65,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "e\n",
      "d\n",
      "a\n"
     ]
    }
   ],
   "source": [
    "napis = 'abcde'\n",
    "print(napis[-1])  # 'e' („ostatni”)\n",
    "print(napis[-2])  # 'd' („drugi od końca”)\n",
    "print(napis[-5])  # 'a' („piąty od końca”)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Łańcuchy możemy też „kroić na plasterki” (_slicing_):"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 66,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "bcd\n",
      "b\n",
      "cd\n",
      "bcd\n",
      "de\n",
      "abc\n",
      "abcde\n"
     ]
    }
   ],
   "source": [
    "napis = 'abcde'\n",
    "print(napis[1:4])  # 'bcd' („znaki od 1. włącznie do 4. wyłącznie”)\n",
    "print(napis[1:2])  # 'b' (to samo co `napis[1]`)\n",
    "print(napis[-3:-1])  # 'cd' (kroić można też stosując indeksowanie od końca)\n",
    "print(napis[1:-1])  # 'bcd' (możemy nawet mieszać te dwa sposoby indeksowania)\n",
    "print(napis[3:])  # 'de' (jeżeli koniec przedziału nie jest podany, to kroimy do samego końca łańcucha)\n",
    "print(napis[:3])  # 'abc' (jeżeli początek przedziału nie jest podany, to kroimy od początku łańcucha)\n",
    "print(napis[:])  # 'abcde' (kopia całego napisu)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 67,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "abcde\n"
     ]
    }
   ],
   "source": [
    "print(napis[:])"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Biblioteka _NumPy_"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Tablice"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Głównym obiektem w NumPy jest **jednorodna**, **wielowymiarowa** tablica. Przykładem takiej tablicy jest macierz `x`.\n",
    "\n",
    "Macierz $x =\n",
    "    \\begin{pmatrix}\n",
    "    1 & 2 & 3  \\\\\n",
    "    4 & 5 & 6  \\\\\n",
    "    7 & 8 & 9\n",
    "    \\end{pmatrix}$\n",
    "można zapisać jako:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 68,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[[1 2 3]\n",
      " [4 5 6]\n",
      " [7 8 9]]\n"
     ]
    }
   ],
   "source": [
    "import numpy as np\n",
    "\n",
    "A = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]])\n",
    "\n",
    "print(A)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 69,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[[1 2 3]\n",
      " [4 5 6]\n",
      " [7 8 9]]\n"
     ]
    }
   ],
   "source": [
    "import numpy as np\n",
    "\n",
    "x = np.array([[1,2,3],[4,5,6],[7,8,9]])\n",
    "print(x)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 70,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[[  1.     2.     3.    -4.5    5.  ]\n",
      " [ 10.     9.    -8.   -13.     0.39]]\n"
     ]
    }
   ],
   "source": [
    "import numpy as np\n",
    "\n",
    "y = np.array([[1, 2, 3, -4.5, 5], [10, 9, -8, -13, 0.39]])\n",
    "print(y)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 71,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "(3, 3)\n"
     ]
    }
   ],
   "source": [
    "print(x.shape)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 72,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "(2, 5)\n"
     ]
    }
   ],
   "source": [
    "print(y.shape)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 73,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[[  1.     2.  ]\n",
      " [  3.    -4.5 ]\n",
      " [  5.    10.  ]\n",
      " [  9.    -8.  ]\n",
      " [-13.     0.39]]\n"
     ]
    }
   ],
   "source": [
    "z = y.reshape(5, 2)\n",
    "print(z)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 74,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "(5, 2)\n"
     ]
    }
   ],
   "source": [
    "print(z.shape)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 75,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[[  1.     2.     3.    -4.5    5.  ]\n",
      " [ 10.     9.    -8.   -13.     0.39]]\n"
     ]
    }
   ],
   "source": [
    "w = z.reshape(2, 5)\n",
    "print(w)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Najczęsciej używane metody tablic typu `array`:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 76,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "(2, 5)\n",
      "[[  1.     2.  ]\n",
      " [  3.    -4.5 ]\n",
      " [  5.    10.  ]\n",
      " [  9.    -8.  ]\n",
      " [-13.     0.39]]\n",
      "(5, 2)\n"
     ]
    }
   ],
   "source": [
    "print(y.shape)\n",
    "\n",
    "z = y.reshape((5, 2))\n",
    "print(z)\n",
    "print(z.shape)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 77,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[[  1.     2.  ]\n",
      " [  3.    -4.5 ]\n",
      " [  5.    10.  ]\n",
      " [  9.    -8.  ]\n",
      " [-13.     0.39]]\n"
     ]
    }
   ],
   "source": [
    "print(z)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 78,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[  3.    -1.5   15.     1.   -12.61]\n"
     ]
    }
   ],
   "source": [
    "print(z.sum(axis=1))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 79,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[[1 2 3]\n",
      " [4 5 6]\n",
      " [7 8 9]]\n",
      "[2. 5. 8.]\n"
     ]
    }
   ],
   "source": [
    "print(x)\n",
    "print(x.mean(axis=1))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 80,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[ 1  2  3  4  5  6  7  8  9 10]\n"
     ]
    }
   ],
   "source": [
    "lista = list(range(1, 11))\n",
    "A = np.array(lista)\n",
    "print(A)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 81,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]\n",
      "[ 1  2  3  4  5  6  7  8  9 10]\n"
     ]
    }
   ],
   "source": [
    "lista = list(range(1, 11))\n",
    "print(lista)\n",
    "A = np.array(lista)\n",
    "print(A)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 82,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[ 1  2  3  4  5  6  7  8  9 10]\n"
     ]
    }
   ],
   "source": [
    "A = np.arange(1, 11)\n",
    "print(A)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 83,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([12, 15, 18])"
      ]
     },
     "execution_count": 83,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "x.sum(axis=0)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 84,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([2., 5., 8.])"
      ]
     },
     "execution_count": 84,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "x.mean(axis=1)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Do tworzenia sekwencji liczbowych jako obiekty typu `array` należy wykorzystać funkcję `arange`."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 85,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])"
      ]
     },
     "execution_count": 85,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "np.arange(10)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 86,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([ 5,  6,  7,  8,  9, 10, 11, 12, 13, 14])"
      ]
     },
     "execution_count": 86,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "np.arange(5, 15)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 87,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([[ 5. ,  5.1,  5.2,  5.3,  5.4,  5.5,  5.6,  5.7,  5.8,  5.9],\n",
       "       [ 6. ,  6.1,  6.2,  6.3,  6.4,  6.5,  6.6,  6.7,  6.8,  6.9],\n",
       "       [ 7. ,  7.1,  7.2,  7.3,  7.4,  7.5,  7.6,  7.7,  7.8,  7.9],\n",
       "       [ 8. ,  8.1,  8.2,  8.3,  8.4,  8.5,  8.6,  8.7,  8.8,  8.9],\n",
       "       [ 9. ,  9.1,  9.2,  9.3,  9.4,  9.5,  9.6,  9.7,  9.8,  9.9],\n",
       "       [10. , 10.1, 10.2, 10.3, 10.4, 10.5, 10.6, 10.7, 10.8, 10.9],\n",
       "       [11. , 11.1, 11.2, 11.3, 11.4, 11.5, 11.6, 11.7, 11.8, 11.9],\n",
       "       [12. , 12.1, 12.2, 12.3, 12.4, 12.5, 12.6, 12.7, 12.8, 12.9],\n",
       "       [13. , 13.1, 13.2, 13.3, 13.4, 13.5, 13.6, 13.7, 13.8, 13.9],\n",
       "       [14. , 14.1, 14.2, 14.3, 14.4, 14.5, 14.6, 14.7, 14.8, 14.9]])"
      ]
     },
     "execution_count": 87,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "np.arange(5, 15, 0.1).reshape(10, 10)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Kształt tablicy można zmienić za pomocą metody `reshape`:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 88,
   "metadata": {
    "scrolled": true
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[ 1  2  3  4  5  6  7  8  9 10 11 12]\n",
      "[[ 1  2  3  4]\n",
      " [ 5  6  7  8]\n",
      " [ 9 10 11 12]]\n"
     ]
    }
   ],
   "source": [
    "x = np.arange(1, 13)\n",
    "print(x)\n",
    "y = x.reshape(3, 4)\n",
    "print(y)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Funkcją podobną do `arange` jest `linspace`, która wypełnia wektor określoną liczbą elementów z przedziału o równych automatycznie obliczonych odstępach (w `arange` należy podać rozmiar kroku):"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 89,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[0.         0.22222222 0.44444444 0.66666667 0.88888889 1.11111111\n",
      " 1.33333333 1.55555556 1.77777778 2.        ]\n"
     ]
    }
   ],
   "source": [
    "x = np.linspace(0, 2, 10)\n",
    "print(x)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Dodatkowe informacje o funkcjach NumPy uzyskuje się za pomocą polecenia `help(nazwa_funkcji)`:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 90,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Help on function shape in module numpy:\n",
      "\n",
      "shape(a)\n",
      "    Return the shape of an array.\n",
      "    \n",
      "    Parameters\n",
      "    ----------\n",
      "    a : array_like\n",
      "        Input array.\n",
      "    \n",
      "    Returns\n",
      "    -------\n",
      "    shape : tuple of ints\n",
      "        The elements of the shape tuple give the lengths of the\n",
      "        corresponding array dimensions.\n",
      "    \n",
      "    See Also\n",
      "    --------\n",
      "    alen\n",
      "    ndarray.shape : Equivalent array method.\n",
      "    \n",
      "    Examples\n",
      "    --------\n",
      "    >>> np.shape(np.eye(3))\n",
      "    (3, 3)\n",
      "    >>> np.shape([[1, 2]])\n",
      "    (1, 2)\n",
      "    >>> np.shape([0])\n",
      "    (1,)\n",
      "    >>> np.shape(0)\n",
      "    ()\n",
      "    \n",
      "    >>> a = np.array([(1, 2), (3, 4)], dtype=[('x', 'i4'), ('y', 'i4')])\n",
      "    >>> np.shape(a)\n",
      "    (2,)\n",
      "    >>> a.shape\n",
      "    (2,)\n",
      "\n"
     ]
    }
   ],
   "source": [
    "help(np.shape)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Tablice mogą składać się z danych różnych typów (ale tylko jednego typu danych równocześnie, stąd jednorodność)."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 91,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "float64\n",
      "[0.1 0.2 0.3]\n",
      "float64\n",
      "float64\n"
     ]
    }
   ],
   "source": [
    "x = np.array([1, 2, 3, 0.5])\n",
    "print(x.dtype)\n",
    "x = np.array([0.1, 0.2, 0.3])\n",
    "print(x)\n",
    "print(x.dtype)\n",
    "x = np.array([1, 2, 3], dtype='float64')\n",
    "print(x.dtype)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Tworzenie tablic składających się z samych zer lub jedynek umożliwiają funkcje `zeros` oraz `ones`:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 92,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[[0. 0. 0. 0.]\n",
      " [0. 0. 0. 0.]\n",
      " [0. 0. 0. 0.]]\n"
     ]
    }
   ],
   "source": [
    "x = np.zeros([3,4])\n",
    "print(x)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 93,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[[1. 1. 1. 1.]\n",
      " [1. 1. 1. 1.]\n",
      " [1. 1. 1. 1.]]\n"
     ]
    }
   ],
   "source": [
    "y = np.ones([3,4])\n",
    "print(y)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 94,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[[1. 1. 1. 1.]\n",
      " [1. 1. 1. 1.]\n",
      " [1. 1. 1. 1.]]\n"
     ]
    }
   ],
   "source": [
    "print(x + y)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 95,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[[ 0  1  2]\n",
      " [ 3  4  5]\n",
      " [ 6  7  8]\n",
      " [ 9 10 11]]\n"
     ]
    }
   ],
   "source": [
    "x = np.arange(12).reshape(4, 3)\n",
    "print(x)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 96,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[[ 5  6  7]\n",
      " [ 8  9 10]\n",
      " [11 12 13]\n",
      " [14 15 16]]\n"
     ]
    }
   ],
   "source": [
    "y = np.arange(5, 17).reshape(4, 3)\n",
    "print(y)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 97,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[[  0   6  14]\n",
      " [ 24  36  50]\n",
      " [ 66  84 104]\n",
      " [126 150 176]]\n"
     ]
    }
   ],
   "source": [
    "print(x * y)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 98,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[[0 1 2 3]\n",
      " [4 5 6 7]]\n"
     ]
    }
   ],
   "source": [
    "A = np.arange(8).reshape(2, 4)\n",
    "print(A)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 99,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[[ 1  2  3]\n",
      " [ 4  5  6]\n",
      " [ 7  8  9]\n",
      " [10 11 12]]\n"
     ]
    }
   ],
   "source": [
    "B = np.arange(1, 13).reshape(4, 3)\n",
    "print(B)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 100,
   "metadata": {
    "scrolled": true
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "(2, 4) (4, 3)\n"
     ]
    }
   ],
   "source": [
    "print(A.shape, B.shape)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 101,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[[ 48  54  60]\n",
      " [136 158 180]]\n",
      "(2, 3)\n"
     ]
    }
   ],
   "source": [
    "C = np.matmul(A, B)\n",
    "print(C)\n",
    "print(C.shape)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 102,
   "metadata": {},
   "outputs": [
    {
     "ename": "ValueError",
     "evalue": "operands could not be broadcast together with shapes (2,4) (4,3) ",
     "output_type": "error",
     "traceback": [
      "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m",
      "\u001b[1;31mValueError\u001b[0m                                Traceback (most recent call last)",
      "\u001b[1;32m<ipython-input-102-a4cedde81ed0>\u001b[0m in \u001b[0;36m<module>\u001b[1;34m\u001b[0m\n\u001b[1;32m----> 1\u001b[1;33m \u001b[0mA\u001b[0m \u001b[1;33m*\u001b[0m \u001b[0mB\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m",
      "\u001b[1;31mValueError\u001b[0m: operands could not be broadcast together with shapes (2,4) (4,3) "
     ]
    }
   ],
   "source": [
    "A * B"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 103,
   "metadata": {},
   "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 4)",
     "output_type": "error",
     "traceback": [
      "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m",
      "\u001b[1;31mValueError\u001b[0m                                Traceback (most recent call last)",
      "\u001b[1;32m<ipython-input-103-89ae99960b6e>\u001b[0m in \u001b[0;36m<module>\u001b[1;34m\u001b[0m\n\u001b[1;32m----> 1\u001b[1;33m \u001b[0mnp\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mmatmul\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mA\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mC\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m",
      "\u001b[1;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 4)"
     ]
    }
   ],
   "source": [
    "np.matmul(A, C)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Podstawowe operacje arytmetyczne"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Operatory arytmetyczne na tablicach w NumPy działają **element po elemencie**."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 104,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[[1 2 3]\n",
      " [1 2 3]]\n"
     ]
    }
   ],
   "source": [
    "A = np.array([[1, 2, 3], [1, 2, 3]])\n",
    "B = np.array([[4, 5, 6], [7, 8, 9]])\n",
    "              \n",
    "print(A)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 105,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[[4 5 6]\n",
      " [7 8 9]]\n"
     ]
    }
   ],
   "source": [
    "print(B)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 106,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[[-3 -3 -3]\n",
      " [-6 -6 -6]]\n"
     ]
    }
   ],
   "source": [
    "print(A - B)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 107,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[[3 3 3]\n",
      " [6 6 6]]\n"
     ]
    }
   ],
   "source": [
    "print(B - A)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 108,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[[ 4 10 18]\n",
      " [ 7 16 27]]\n"
     ]
    }
   ],
   "source": [
    "print(A * B)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 109,
   "metadata": {},
   "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[1;31m---------------------------------------------------------------------------\u001b[0m",
      "\u001b[1;31mValueError\u001b[0m                                Traceback (most recent call last)",
      "\u001b[1;32m<ipython-input-109-04c68bb92949>\u001b[0m in \u001b[0;36m<module>\u001b[1;34m\u001b[0m\n\u001b[1;32m----> 1\u001b[1;33m \u001b[0mnp\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mmatmul\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mA\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mB\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m",
      "\u001b[1;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": [
    "np.matmul(A, B)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 110,
   "metadata": {
    "scrolled": true
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "(2, 3)\n",
      "(3, 4)\n",
      "\n",
      "[[1 2 3]\n",
      " [1 2 3]]\n",
      "[[1 2 3 4]\n",
      " [9 8 7 6]\n",
      " [2 4 6 7]]\n",
      "[[25 30 35 37]\n",
      " [25 30 35 37]]\n",
      "\n",
      "(2, 3) (3, 4)\n",
      "(2, 4)\n"
     ]
    }
   ],
   "source": [
    "print(A.shape)\n",
    "B = np.array([[1, 2, 3, 4], [9, 8, 7, 6], [2, 4, 6, 7]])\n",
    "print(B.shape)\n",
    "\n",
    "print()\n",
    "\n",
    "print(A)\n",
    "print(B)\n",
    "C = np.matmul(A, B)\n",
    "print(C)\n",
    "\n",
    "print()\n",
    "\n",
    "print(A.shape, B.shape)\n",
    "print(C.shape)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 111,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([[25, 30, 35, 37],\n",
       "       [25, 30, 35, 37]])"
      ]
     },
     "execution_count": 111,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "np.dot(A, B)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 112,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[2. 3. 4.]\n"
     ]
    }
   ],
   "source": [
    "import numpy as np\n",
    "\n",
    "a = np.array([3, 4, 5])\n",
    "b = np.ones(3)\n",
    "print(a - b)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Za mnożenie macierzy odpowiada funkcja `dot` (nie operator `*`):"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 113,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[[1 2]\n",
      " [3 4]]\n"
     ]
    }
   ],
   "source": [
    "a = np.array([[1, 2], [3, 4]])\n",
    "print(a)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 114,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[[1 2]\n",
      " [3 4]]\n"
     ]
    }
   ],
   "source": [
    "b = np.array([[1, 2], [3, 4]])\n",
    "print(b)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 115,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([[ 1,  4],\n",
       "       [ 9, 16]])"
      ]
     },
     "execution_count": 115,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "a * b"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 116,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([[ 7, 10],\n",
       "       [15, 22]])"
      ]
     },
     "execution_count": 116,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "np.dot(a,b)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Przykłady innych operacji dodawania i mnożenia:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 117,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([[5., 5.],\n",
       "       [5., 5.]])"
      ]
     },
     "execution_count": 117,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "a = np.zeros((2, 2), dtype='float')\n",
    "a += 5\n",
    "a"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 118,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([[25., 25.],\n",
       "       [25., 25.]])"
      ]
     },
     "execution_count": 118,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "a *= 5\n",
    "a"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 119,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([[50., 50.],\n",
       "       [50., 50.]])"
      ]
     },
     "execution_count": 119,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "a + a"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Sklejanie tablic:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 120,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([1, 2, 3, 4, 5, 6, 7, 8, 9])"
      ]
     },
     "execution_count": 120,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "a = np.array([1, 2, 3])\n",
    "b = np.array([4, 5, 6])\n",
    "c = np.array([7, 8, 9])\n",
    "np.hstack([a, b, c])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 121,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([[1, 2, 3],\n",
       "       [4, 5, 6],\n",
       "       [7, 8, 9]])"
      ]
     },
     "execution_count": 121,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "np.vstack([a, b, c])"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Typowe funkcje matematyczne:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 122,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([3.14159265, 4.44288294, 5.44139809, 6.28318531])"
      ]
     },
     "execution_count": 122,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "x = np.arange(1, 5)\n",
    "np.sqrt(x) * np.pi"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 123,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "16"
      ]
     },
     "execution_count": 123,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "2**4"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 124,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "16"
      ]
     },
     "execution_count": 124,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "np.power(2, 4)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 125,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "1.0"
      ]
     },
     "execution_count": 125,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "np.log(np.e)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 126,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "4"
      ]
     },
     "execution_count": 126,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "x = np.arange(5)\n",
    "x.max() - x.min()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Indeksy i zakresy"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Tablice jednowymiarowe zachowują sie podobnie do zwykłych list pythonowych."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 127,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([2, 3])"
      ]
     },
     "execution_count": 127,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "a = np.arange(10)\n",
    "a[2:4]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 128,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([0, 2, 4, 6, 8])"
      ]
     },
     "execution_count": 128,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "a[:10:2]  # elementy do 10., co drugi element"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 130,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([9, 8, 7, 6, 5, 4, 3, 2, 1, 0])"
      ]
     },
     "execution_count": 130,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "a[::-1]  # wszytkie elementy tablicy `a`, ale w odwróconej kolejności"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Tablice wielowymiarowe mają po jednym indeksie na wymiar:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 131,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([[ 0,  1,  2,  3],\n",
       "       [ 4,  5,  6,  7],\n",
       "       [ 8,  9, 10, 11]])"
      ]
     },
     "execution_count": 131,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "x = np.arange(12).reshape(3, 4)\n",
    "x"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 133,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "11"
      ]
     },
     "execution_count": 133,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "x[2, 3]  # wiersz 2, kolumna 3"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 134,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([1, 5, 9])"
      ]
     },
     "execution_count": 134,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "x[:, 1]  # kolumna 1"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 135,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([4, 5, 6, 7])"
      ]
     },
     "execution_count": 135,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "x[1, :]  # wiersz 1"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 136,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([[ 4,  5,  6,  7],\n",
       "       [ 8,  9, 10, 11]])"
      ]
     },
     "execution_count": 136,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "x[1:3, :]  # wiersze od 1. włącznie do 3. wyłącznie"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Warunki"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Warunki pozwalają na selekcję elementów tablicy."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 138,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([2, 2, 2, 3, 3, 3])"
      ]
     },
     "execution_count": 138,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "a = np.array([1, 1, 1, 2, 2, 2, 3, 3, 3])\n",
    "a[a > 1]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 139,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([3, 3, 3])"
      ]
     },
     "execution_count": 139,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "a[a == 3]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 141,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(array([0, 1, 2, 3, 4, 5], dtype=int64),)"
      ]
     },
     "execution_count": 141,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "np.where(a < 3)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 142,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([0, 1, 2, 3, 4, 5], dtype=int64)"
      ]
     },
     "execution_count": 142,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "np.where(a < 3)[0]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 143,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(array([], dtype=int64),)"
      ]
     },
     "execution_count": 143,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "np.where(a > 9)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Pętle i wypisywanie"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 145,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[0 1 2 3]\n",
      "[4 5 6 7]\n",
      "[ 8  9 10 11]\n"
     ]
    }
   ],
   "source": [
    "for row in x:\n",
    "    print(row)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 146,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "0\n",
      "1\n",
      "2\n",
      "3\n",
      "4\n",
      "5\n",
      "6\n",
      "7\n",
      "8\n",
      "9\n",
      "10\n",
      "11\n"
     ]
    }
   ],
   "source": [
    "for row in x:\n",
    "    for element in row:\n",
    "        print(element)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 147,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "0\n",
      "1\n",
      "2\n",
      "3\n",
      "4\n",
      "5\n",
      "6\n",
      "7\n",
      "8\n",
      "9\n",
      "10\n",
      "11\n"
     ]
    }
   ],
   "source": [
    "# Operacja `.flat` \"spłaszcza\" macierz\n",
    "for element in x.flat:\n",
    "    print(element)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Liczby losowe"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 148,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([9, 7, 1, 6, 5])"
      ]
     },
     "execution_count": 148,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "np.random.randint(0, 10, 5)  # Tablica złożona z 5 liczb całkowitych wylosowanych z zakresu od 0 do 10"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 149,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([-0.5127886 , -0.4507017 , -1.06312973,  1.22150748,  0.27790976])"
      ]
     },
     "execution_count": 149,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "np.random.normal(0, 1, 5)  # Tablica złożona z 5 liczb wylosowanych z rozkładu normalnego (0, 1)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 150,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([1.34207418, 1.70197756, 1.16472435, 0.57619858, 1.22382641])"
      ]
     },
     "execution_count": 150,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "np.random.uniform(0, 2, 5)  # Tablica złożona z 5 liczb wylosowanych z rozkładu jednostajnego na przedziale (0, 1)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Macierze"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "NumPy jest pakietem wykorzystywanym do obliczeń w dziedzinie algebry liniowej, co jeszcze szczególnie przydatne w uczeniu maszynowym. \n",
    "\n",
    "Wektor o wymiarach $1 \\times N$ \n",
    "$$\n",
    "    x =\n",
    "    \\begin{pmatrix}\n",
    "    x_{1}  \\\\\n",
    "    x_{2}  \\\\\n",
    "    \\vdots \\\\\n",
    "    x_{N}\n",
    "    \\end{pmatrix} \n",
    "$$\n",
    "\n",
    "i jego transpozycję $x^\\top = (x_{1}, x_{2},\\ldots,x_{N})$ można wyrazić w Pythonie w następujący sposób:"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**Transpozycja** to operacja zamiany wierszy na kolumny i na odwrót."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 172,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[[0 1 2]\n",
      " [3 4 5]\n",
      " [6 7 8]]\n"
     ]
    }
   ],
   "source": [
    "A = np.arange(9).reshape(3, 3)\n",
    "print(A)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 173,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[[0 3 6]\n",
      " [1 4 7]\n",
      " [2 5 8]]\n"
     ]
    }
   ],
   "source": [
    "print(A.T)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 151,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(3, 1)"
      ]
     },
     "execution_count": 151,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "import numpy as np\n",
    "\n",
    "x = np.array([[1, 2, 3]]).T\n",
    "x.shape"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 152,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(1, 3)"
      ]
     },
     "execution_count": 152,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "xt = x.T\n",
    "xt.shape"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**Macierz kolumnowa** w NumPy.\n",
    "$$X =\n",
    "    \\begin{pmatrix}\n",
    "    3  \\\\\n",
    "    4  \\\\\n",
    "    5  \\\\\n",
    "    6  \n",
    "    \\end{pmatrix}$$"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 153,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([[3],\n",
       "       [4],\n",
       "       [5],\n",
       "       [6]])"
      ]
     },
     "execution_count": 153,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "x = np.array([[3,4,5,6]]).T\n",
    "x"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**Macierz wierszowa** w NumPy.\n",
    "$$ X =\n",
    "    \\begin{pmatrix}\n",
    "    3 & 4 & 5 & 6\n",
    "    \\end{pmatrix}$$"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 154,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([[3, 4, 5, 6]])"
      ]
     },
     "execution_count": 154,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "x = np.array([[3,4,5,6]])\n",
    "x"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Oprócz obiektów typu `array` istnieje wyspecjalizowany obiekt `matrix`, dla którego operacje `*` (mnożenie) oraz `**-1` (odwracanie) są określone w sposób właściwy dla macierzy (w przeciwieństwie do operacji elementowych dla obiektów `array`)."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 158,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[[1 2 3]\n",
      " [4 5 6]\n",
      " [7 8 9]]\n"
     ]
    }
   ],
   "source": [
    "x = np.array([1,2,3,4,5,6,7,8,9]).reshape(3,3)\n",
    "print(x)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 159,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[[4 6 3]\n",
      " [8 7 1]\n",
      " [3 0 3]]\n"
     ]
    }
   ],
   "source": [
    "y = np.array([4,6,3,8,7,1,3,0,3]).reshape(3,3)\n",
    "print(y)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 160,
   "metadata": {},
   "outputs": [],
   "source": [
    "X = np.matrix(x)\n",
    "Y = np.matrix(y)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 161,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[[ 4 12  9]\n",
      " [32 35  6]\n",
      " [21  0 27]]\n"
     ]
    }
   ],
   "source": [
    "print(x * y)  # Tablice np.array mnożone są element po elemencie"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 162,
   "metadata": {
    "scrolled": true
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[[ 29  20  14]\n",
      " [ 74  59  35]\n",
      " [119  98  56]]\n"
     ]
    }
   ],
   "source": [
    "print(X * Y)  # Macierze np.matrix mnożone są macierzowo"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 164,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[[ 29  20  14]\n",
      " [ 74  59  35]\n",
      " [119  98  56]]\n"
     ]
    }
   ],
   "source": [
    "print(np.matmul(x, y))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**Wyznacznik macierzy**"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 165,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "33.000000000000014"
      ]
     },
     "execution_count": 165,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "a = np.array([[3,-9],[2,5]])\n",
    "np.linalg.det(a)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**Macierz odwrotna**"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 166,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([[-4, -2],\n",
       "       [ 5,  5]])"
      ]
     },
     "execution_count": 166,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "A = np.array([[-4,-2],[5,5]])\n",
    "A"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 167,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([[-0.5, -0.2],\n",
       "       [ 0.5,  0.4]])"
      ]
     },
     "execution_count": 167,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "invA = np.linalg.inv(A)\n",
    "invA"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 168,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([[1., 0.],\n",
       "       [0., 1.]])"
      ]
     },
     "execution_count": 168,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "np.round(np.dot(A, invA))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "(ponieważ $AA^{-1} = A^{-1}A = I$)."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**Wartości i wektory własne**"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 169,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([[1, 0, 0],\n",
       "       [0, 2, 0],\n",
       "       [0, 0, 3]])"
      ]
     },
     "execution_count": 169,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "a = np.diag((1, 2, 3))\n",
    "a"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 170,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[1. 2. 3.]\n",
      "[[1. 0. 0.]\n",
      " [0. 1. 0.]\n",
      " [0. 0. 1.]]\n"
     ]
    }
   ],
   "source": [
    "w, v = np.linalg.eig(a)\n",
    "print(w)  # wartości własne\n",
    "print(v)  # wektory własne"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Zadania"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Zadanie 1.1 (1 pkt)\n",
    "\n",
    "Dla danej listy `input_list` zawierającej liczby utwórz nową listę `output_list`, która będzie zawierała kwadraty liczb dodatnich z `input_list`. Użyj _list comprehension_!"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Przykładowe dane\n",
    "\n",
    "input_list = [34.6, -203.4, 44.9, 68.3, -12.2, 44.6, 12.7]"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Zadanie 1.2 (1 pkt)\n",
    "\n",
    "Za pomocą jednowierszowego polecenia utwórz następującą macierz jako obiekt typu `array`:\n",
    "$$A = \\begin{pmatrix}\n",
    "1       & 2      & \\cdots & 10      \\\\\n",
    "11      & 12     & \\cdots & 20      \\\\\n",
    "\\vdots  & \\ddots & \\ddots & \\vdots  \\\\\n",
    "41      & 42     & \\cdots & 50 \n",
    "\\end{pmatrix}$$"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Zadanie 1.3 (1 pkt)\n",
    "\n",
    "Dla macierzy $A$ z zadania 1.2:\n",
    " * określ liczbę elementów, kolumn i wierszy,\n",
    " * stwórz wektory średnich po wierszach oraz po kolumnach,\n",
    " * wypisz jej trzecią kolumnę,\n",
    " * wypisz jej czwarty wiersz.\n",
    " \n",
    "Użyj odpowiednich metod obiektu `array`."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Zadanie 1.4 (1 pkt)\n",
    "\n",
    "Utwórz macierze\n",
    "$$ A = \\begin{pmatrix}\n",
    "0 & 4 & -2 \\\\\n",
    "-4 & -3 & 0\n",
    "\\end{pmatrix} $$\n",
    "$$ B = \\begin{pmatrix}\n",
    "0 & 1 \\\\\n",
    "1 & -1 \\\\\n",
    "2 & 3\n",
    "\\end{pmatrix} $$\n",
    "oraz wektor\n",
    "$$ x = \\begin{pmatrix}\n",
    "2 \\\\\n",
    "1 \\\\\n",
    "0\n",
    "\\end{pmatrix} $$\n",
    "\n",
    "Oblicz:\n",
    " * iloczyn macierzy $A$ z wektorem $x$ \n",
    " * iloczyn macierzy $A \\cdot B$\n",
    " * wyznacznik $\\det(A \\cdot B)$\n",
    " * wynik działania $(A \\cdot B)^\\top - B^\\top \\cdot A^\\top$"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Zadanie 1.5 (1 pkt)\n",
    "\n",
    "Czym różni się operacja `A**-1` dla obiektów typu `array` i `matrix`? Pokaż na przykładzie."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Zadanie 1.6 (1 pkt)\n",
    "\n",
    "Dla macierzy $X = \\left[\n",
    "      \\begin{array}{rrr}\n",
    "        1 & 2 & 3\\\\\n",
    "        1 & 3 & 6 \\\\\n",
    "      \\end{array}\n",
    "    \\right]$ oraz wektora $y = \\left[\n",
    "      \\begin{array}{r}\n",
    "        5 \\\\\n",
    "        6 \\\\\n",
    "      \\end{array}\n",
    "    \\right]$ oblicz wynikowy wektor: \n",
    "$$ \\theta = (X^\\top \\, X)^{-1} \\, X^\\top \\, y \\, . $$\n",
    "Wykonaj te same obliczenia raz na obiektach typu `array`, a raz na obiektach typu `matrix`.\n",
    "W przypadku obiektów typu `matrix` zastosuj możliwie krótki zapis. "
   ]
  }
 ],
 "metadata": {
  "celltoolbar": "Slideshow",
  "kernelspec": {
   "display_name": "Python 3",
   "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.3"
  },
  "livereveal": {
   "start_slideshow_at": "selected",
   "theme": "amu"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 4
}