{ "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": 1, "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": 2, "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": 3, "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": 4, "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": 5, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]" ] }, "execution_count": 5, "metadata": {}, "output_type": "execute_result" } ], "source": [ "list(range(1, 11))" ] }, { "cell_type": "code", "execution_count": 6, "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": 7, "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": 8, "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": 9, "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": 10, "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": 11, "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": 12, "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": 13, "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": 14, "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": 15, "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:]) # 'cde' (jeżeli koniec przedziału nie jest podany, to kroimy do samego końca łańcucha)\n", "print(napis[:3]) # 'ab' (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": 16, "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": 17, "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": 18, "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": 19, "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": 20, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "(3, 3)\n" ] } ], "source": [ "print(x.shape)" ] }, { "cell_type": "code", "execution_count": 21, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "(2, 5)\n" ] } ], "source": [ "print(y.shape)" ] }, { "cell_type": "code", "execution_count": 22, "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": 23, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "(5, 2)\n" ] } ], "source": [ "print(z.shape)" ] }, { "cell_type": "code", "execution_count": 24, "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": 25, "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": 26, "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": 27, "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": 28, "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": 29, "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": 30, "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": 31, "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": 32, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "array([12, 15, 18])" ] }, "execution_count": 32, "metadata": {}, "output_type": "execute_result" } ], "source": [ "x.sum(axis=0)" ] }, { "cell_type": "code", "execution_count": 33, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "array([2., 5., 8.])" ] }, "execution_count": 33, "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": 34, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])" ] }, "execution_count": 34, "metadata": {}, "output_type": "execute_result" } ], "source": [ "np.arange(10)" ] }, { "cell_type": "code", "execution_count": 35, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "array([ 5, 6, 7, 8, 9, 10, 11, 12, 13, 14])" ] }, "execution_count": 35, "metadata": {}, "output_type": "execute_result" } ], "source": [ "np.arange(5, 15)" ] }, { "cell_type": "code", "execution_count": 36, "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": 36, "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": 37, "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": 38, "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": 39, "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": 40, "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": 41, "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": 42, "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": 43, "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": 44, "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": 45, "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": 46, "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": 47, "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": 48, "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": 49, "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": 50, "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": 51, "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\u001b[0m in \u001b[0;36m\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": null, "metadata": {}, "outputs": [], "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": null, "metadata": {}, "outputs": [], "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": null, "metadata": {}, "outputs": [], "source": [ "print(B)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "print(A - B)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "print(B - A)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "print(A * B)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "np.matmul(A, B)" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "scrolled": true }, "outputs": [], "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": null, "metadata": {}, "outputs": [], "source": [ "np.dot(A, B)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "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": null, "metadata": {}, "outputs": [], "source": [ "a = np.array([[1, 2], [3, 4]])\n", "print(a)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "b = np.array([[1, 2], [3, 4]])\n", "print(b)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "a * b" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "np.dot(a,b)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Przykłady innych operacji dodawania i mnożenia:" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "a = np.zeros((2, 2), dtype='float')\n", "a += 5\n", "a" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "a *= 5\n", "a" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "a + a" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Sklejanie tablic:" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "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": null, "metadata": {}, "outputs": [], "source": [ "np.vstack([a, b, c])" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Typowe funkcje matematyczne:" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "x = np.arange(1, 5)\n", "np.sqrt(x) * np.pi" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "2**4" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "np.power(2, 4)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "np.log(np.e)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "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": null, "metadata": {}, "outputs": [], "source": [ "a = np.arange(10)\n", "a[2:4]" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "a[:10:2]" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "a[::-1]" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Tablice wielowymiarowe mają po jednym indeksie na wymiar:" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "x = np.arange(12).reshape(3, 4)\n", "x" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "x[2, 3]" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "x[:, 1]" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "x[1, :]" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "x[1:3, :]" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Warunki" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Warunki pozwalają na selekcję elementów tablicy." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "a = np.array([1, 1, 1, 2, 2, 2, 3, 3, 3])\n", "a[a > 1]" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "a[a == 3]" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "np.where(a < 3)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "np.where(a < 3)[0]" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "np.where(a > 9)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Pętle i wypisywanie" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "for row in x:\n", " print row" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "for element in x.flat:\n", " print element, " ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Liczby losowe" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "np.random.randint(0, 10, 5)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "np.random.normal(0, 1, 5) " ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "np.random.uniform(0, 2, 5)" ] }, { "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": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "import numpy as np\n", "\n", "x = np.array([[1, 2, 3]]).T\n", "x.shape" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "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": null, "metadata": {}, "outputs": [], "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": null, "metadata": {}, "outputs": [], "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": null, "metadata": {}, "outputs": [], "source": [ "x = np.array([1,2,3,4,5,6,7,8,9]).reshape(3,3)\n", "x" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "X = np.matrix(x)\n", "X" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "**Wyznacznik macierzy**" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "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": null, "metadata": {}, "outputs": [], "source": [ "A = np.array([[-4,-2],[5,5]])\n", "A" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "invA = np.linalg.inv(A)\n", "invA" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "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": null, "metadata": {}, "outputs": [], "source": [ "a = np.diag((1, 2, 3))\n", "a" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "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 }