{ "nbformat": 4, "nbformat_minor": 0, "metadata": { "colab": { "name": "05_numpy.ipynb", "provenance": [], "collapsed_sections": [] }, "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.6.9" } }, "cells": [ { "cell_type": "markdown", "metadata": { "id": "ADioeXA4e9DY" }, "source": [ "# Python для анализа данных" ] }, { "cell_type": "code", "metadata": { "id": "Qri5nDu-eSXQ" }, "source": [ "import numpy as np" ], "execution_count": 1, "outputs": [] }, { "cell_type": "markdown", "metadata": { "id": "w5l3lSPkeSXN" }, "source": [ "# Библиотека `numpy`\n", "\n", "![440px-NumPy_logo_2020.svg.png](data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAbgAAADGCAYAAACglZW2AAAABGdBTUEAALGPC/xhBQAAACBjSFJNAAB6JgAAgIQAAPoAAACA6AAAdTAAAOpgAAA6mAAAF3CculE8AAAABmJLR0QA/wD/AP+gvaeTAAAlWklEQVR42u3deXxU1d0/8M/33smGKG5Y99YFq6JmJkld20etW9FMKMKkah+X6mNsa11QSIKADFghiVgVt4JtRXHBBBBmAqiPFq21VZ+QSbBxKa517c8FqpBlZu79/v5IUGTLnczNZGbyeb9evl4CM3c599zzuefOvecARERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERElKaERdDPVMW/qKVMgDOg9u2h8uI3WShERAy4jDZ6cfPpti2zAJT0/JUNYLFlyZQV53n/yRIiImLAZXqwbYlBR0TEgMuqYNtm0KlgcuM431qWIBERAy59qErp4jWlovaNCQQbg46IiAGX3sFmqE5TaLFLS41BZKFCb2LQEREx4LIh2LYZdGJbM/jUJRERAy4bgo1BR0TEgMvqYGPQEREx4Po32MS2ghApSpOtikFkoRmPT196XslbPEhERAy4TA82Bh0RUYIMFsG3ndXw6m6AfRrEODKNNzMHqhdaplHnDzcN4VEjImIPzrExS1r3ilvWdYBcDaAgvXqZ8iJgV4fLi57jkSIiYsAlGXTGNYDmD/DRek0U00IBXwOPDBERA84Vox995QDbY00AUJHyoBN9X2zjt3n45x8bysstHg0iIgZcpgfd54Dc8tWGdXc8+4tTO1n6REQMuK8Fg2qsPqp1HFR32ecL64F5V5TE3Fiuv77pQIjnekCvAJDn8mZvBPSufLVnNZSX/MeNBZbVr/5JzPT8Y+XYwg9Y7YmIAZfhwdZ01JpzRO3pAHw9f/2eKG6LDR36+5Vnj+hyYz1nL27+rmkb17kUdDEI7rfs2LQV5cd+4kqwLY6cpBZmQvBfAKIQzI+LcRODjogYcNkRbFt6T1Rmfjl83Z+ePfXUuGtBp3IDFJcC8CT4dRvAYtOyJrn1Xtvo+jVH22JNBRDYxj8z6IiIAZdpwWaoPUMBr8O9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)\n", "\n", "Пакет `numpy` предоставляет $n$-мерные однородные массивы (все элементы одного типа); в них нельзя вставить или удалить элемент в произвольном месте. В `numpy` реализовано много операций над массивами в целом. Если задачу можно решить, произведя некоторую последовательность операций над массивами, то это будет столь же эффективно, как в `C` или `matlab` — львиная доля времени тратится в библиотечных функциях, написанных на `C`.\n", "\n", "*Замечание.* Модуль `numpy.random` не рассматривается целенаправленно. Вместо него рассмотри модуль `scipy.stats`, который больше подходит под вероятностно-статистические задачи.\n", "\n", "## 1. Одномерные массивы\n", "\n", "#### 1.1 Типы массивов, атрибуты" ] }, { "cell_type": "markdown", "metadata": { "id": "4OYggcLMeSXY" }, "source": [ "Можно преобразовать список в массив." ] }, { "cell_type": "code", "metadata": { "id": "60DzfgyMeSXa", "colab": { "base_uri": "https://localhost:8080/" }, "outputId": "d67812f0-fa64-4ccf-b0f3-13c7d852c81f" }, "source": [ "a = np.array([0, 2, 1])\n", "a, type(a)" ], "execution_count": 2, "outputs": [ { "output_type": "execute_result", "data": { "text/plain": [ "(array([0, 2, 1]), numpy.ndarray)" ] }, "metadata": { "tags": [] }, "execution_count": 2 } ] }, { "cell_type": "markdown", "metadata": { "id": "Zus_bnvFeSXf" }, "source": [ "`print` печатает массивы в удобной форме." ] }, { "cell_type": "code", "metadata": { "id": "3CY4rY0GeSXg", "colab": { "base_uri": "https://localhost:8080/" }, "outputId": "47cdbb23-1164-4ee6-8c87-580fb7d612f7" }, "source": [ "print(a)" ], "execution_count": 3, "outputs": [ { "output_type": "stream", "text": [ "[0 2 1]\n" ], "name": "stdout" } ] }, { "cell_type": "markdown", "metadata": { "id": "GWrTlCJieSXk" }, "source": [ "Класс `ndarray` имеет много методов." ] }, { "cell_type": "code", "metadata": { "id": "KhZ0kil4eSXl", "scrolled": true, "colab": { "base_uri": "https://localhost:8080/" }, "outputId": "b13032be-59e3-4093-eb3f-1306a5f62e12" }, "source": [ "set(dir(a)) - set(dir(object))" ], "execution_count": 4, "outputs": [ { "output_type": "execute_result", "data": { "text/plain": [ "{'T',\n", " '__abs__',\n", " '__add__',\n", " '__and__',\n", " '__array__',\n", " '__array_finalize__',\n", " '__array_function__',\n", " '__array_interface__',\n", " '__array_prepare__',\n", " '__array_priority__',\n", " '__array_struct__',\n", " '__array_ufunc__',\n", " '__array_wrap__',\n", " '__bool__',\n", " '__complex__',\n", " '__contains__',\n", " '__copy__',\n", " '__deepcopy__',\n", " '__delitem__',\n", " '__divmod__',\n", " '__float__',\n", " '__floordiv__',\n", " '__getitem__',\n", " '__iadd__',\n", " '__iand__',\n", " '__ifloordiv__',\n", " '__ilshift__',\n", " '__imatmul__',\n", " '__imod__',\n", " '__imul__',\n", " '__index__',\n", " '__int__',\n", " '__invert__',\n", " '__ior__',\n", " '__ipow__',\n", " '__irshift__',\n", " '__isub__',\n", " '__iter__',\n", " '__itruediv__',\n", " '__ixor__',\n", " '__len__',\n", " '__lshift__',\n", " '__matmul__',\n", " '__mod__',\n", " '__mul__',\n", " '__neg__',\n", " '__or__',\n", " '__pos__',\n", " '__pow__',\n", " '__radd__',\n", " '__rand__',\n", " '__rdivmod__',\n", " '__rfloordiv__',\n", " '__rlshift__',\n", " '__rmatmul__',\n", " '__rmod__',\n", " '__rmul__',\n", " '__ror__',\n", " '__rpow__',\n", " '__rrshift__',\n", " '__rshift__',\n", " '__rsub__',\n", " '__rtruediv__',\n", " '__rxor__',\n", " '__setitem__',\n", " '__setstate__',\n", " '__sub__',\n", " '__truediv__',\n", " '__xor__',\n", " 'all',\n", " 'any',\n", " 'argmax',\n", " 'argmin',\n", " 'argpartition',\n", " 'argsort',\n", " 'astype',\n", " 'base',\n", " 'byteswap',\n", " 'choose',\n", " 'clip',\n", " 'compress',\n", " 'conj',\n", " 'conjugate',\n", " 'copy',\n", " 'ctypes',\n", " 'cumprod',\n", " 'cumsum',\n", " 'data',\n", " 'diagonal',\n", " 'dot',\n", " 'dtype',\n", " 'dump',\n", " 'dumps',\n", " 'fill',\n", " 'flags',\n", " 'flat',\n", " 'flatten',\n", " 'getfield',\n", " 'imag',\n", " 'item',\n", " 'itemset',\n", " 'itemsize',\n", " 'max',\n", " 'mean',\n", " 'min',\n", " 'nbytes',\n", " 'ndim',\n", " 'newbyteorder',\n", " 'nonzero',\n", " 'partition',\n", " 'prod',\n", " 'ptp',\n", " 'put',\n", " 'ravel',\n", " 'real',\n", " 'repeat',\n", " 'reshape',\n", " 'resize',\n", " 'round',\n", " 'searchsorted',\n", " 'setfield',\n", " 'setflags',\n", " 'shape',\n", " 'size',\n", " 'sort',\n", " 'squeeze',\n", " 'std',\n", " 'strides',\n", " 'sum',\n", " 'swapaxes',\n", " 'take',\n", " 'tobytes',\n", " 'tofile',\n", " 'tolist',\n", " 'tostring',\n", " 'trace',\n", " 'transpose',\n", " 'var',\n", " 'view'}" ] }, "metadata": { "tags": [] }, "execution_count": 4 } ] }, { "cell_type": "markdown", "metadata": { "id": "j2Yro8nMeSXo" }, "source": [ "Наш массив одномерный." ] }, { "cell_type": "code", "metadata": { "id": "OMpgblpYeSXp", "colab": { "base_uri": "https://localhost:8080/" }, "outputId": "8396d3af-0c5e-4b57-a880-703b75815e33" }, "source": [ "a.ndim" ], "execution_count": 5, "outputs": [ { "output_type": "execute_result", "data": { "text/plain": [ "1" ] }, "metadata": { "tags": [] }, "execution_count": 5 } ] }, { "cell_type": "markdown", "metadata": { "id": "LB3skyaOeSXs" }, "source": [ "В $n$-мерном случае возвращается кортеж размеров по каждой координате." ] }, { "cell_type": "code", "metadata": { "id": "ivBL1F1PeSXs", "colab": { "base_uri": "https://localhost:8080/" }, "outputId": "586db3a2-9e33-437d-a3d6-8cf4d7423ff3" }, "source": [ "a.shape" ], "execution_count": 6, "outputs": [ { "output_type": "execute_result", "data": { "text/plain": [ "(3,)" ] }, "metadata": { "tags": [] }, "execution_count": 6 } ] }, { "cell_type": "markdown", "metadata": { "id": "RalMfmjfeSXv" }, "source": [ "`size` — это полное число элементов в массиве; `len` — размер по первой координате (в 1-мерном случае это то же самое)." ] }, { "cell_type": "code", "metadata": { "id": "twpTTZ9ieSXw", "colab": { "base_uri": "https://localhost:8080/" }, "outputId": "7dc28f90-22c1-4151-a251-3fa3f3e8f30a" }, "source": [ "len(a), a.size" ], "execution_count": 7, "outputs": [ { "output_type": "execute_result", "data": { "text/plain": [ "(3, 3)" ] }, "metadata": { "tags": [] }, "execution_count": 7 } ] }, { "cell_type": "markdown", "metadata": { "id": "eCtLf6OyeSXx" }, "source": [ "`numpy` предоставляет несколько типов для целых (`int16`, `int32`, `int64`) и чисел с плавающей точкой (`float32`, `float64`)." ] }, { "cell_type": "code", "metadata": { "id": "IHuuDB2peSXy", "colab": { "base_uri": "https://localhost:8080/" }, "outputId": "9be7ebf8-5266-4888-9403-860b220ae72c" }, "source": [ "a.dtype, a.dtype.name, a.itemsize" ], "execution_count": 8, "outputs": [ { "output_type": "execute_result", "data": { "text/plain": [ "(dtype('int64'), 'int64', 8)" ] }, "metadata": { "tags": [] }, "execution_count": 8 } ] }, { "cell_type": "markdown", "metadata": { "id": "xmBioWwXeSX9" }, "source": [ "Массив чисел с плавающей точкой." ] }, { "cell_type": "code", "metadata": { "id": "iZ9WpKkVeSX9", "scrolled": true, "colab": { "base_uri": "https://localhost:8080/" }, "outputId": "b76ffa05-4bc6-42d8-d3b4-aba13f12dea5" }, "source": [ "b = np.array([0., 2, 1])\n", "b.dtype" ], "execution_count": 9, "outputs": [ { "output_type": "execute_result", "data": { "text/plain": [ "dtype('float64')" ] }, "metadata": { "tags": [] }, "execution_count": 9 } ] }, { "cell_type": "markdown", "metadata": { "id": "EG3m0QNkeSX_" }, "source": [ "Точно такой же массив." ] }, { "cell_type": "code", "metadata": { "id": "zB1Gle6peSYA", "colab": { "base_uri": "https://localhost:8080/" }, "outputId": "fd568b10-5cb5-43eb-df83-cc786a64ca46" }, "source": [ "c = np.array([0, 2, 1], dtype=np.float64)\n", "print(c)" ], "execution_count": 10, "outputs": [ { "output_type": "stream", "text": [ "[0. 2. 1.]\n" ], "name": "stdout" } ] }, { "cell_type": "markdown", "metadata": { "id": "T_gqbazheSYC" }, "source": [ "Преобразование данных" ] }, { "cell_type": "code", "metadata": { "id": "ok8MtEvaeSYC", "colab": { "base_uri": "https://localhost:8080/" }, "outputId": "39d9b0e2-5cc9-4d54-b33e-661a43bf7522" }, "source": [ "print(c.dtype)\n", "print(c.astype(int))\n", "print(c.astype(str))" ], "execution_count": 11, "outputs": [ { "output_type": "stream", "text": [ "float64\n", "[0 2 1]\n", "['0.0' '2.0' '1.0']\n" ], "name": "stdout" } ] }, { "cell_type": "markdown", "metadata": { "id": "G1DRYeu5eSX0" }, "source": [ "#### 1.2 Индексация\n", "\n", "Индексировать массив можно обычным образом." ] }, { "cell_type": "code", "metadata": { "id": "Y9tGXwDIeSX1", "colab": { "base_uri": "https://localhost:8080/" }, "outputId": "9251016c-eeaa-48a1-f877-f7f13c952da3" }, "source": [ "a[1]" ], "execution_count": 12, "outputs": [ { "output_type": "execute_result", "data": { "text/plain": [ "2" ] }, "metadata": { "tags": [] }, "execution_count": 12 } ] }, { "cell_type": "markdown", "metadata": { "id": "rmKD1RweeSX3" }, "source": [ "Массивы — изменяемые объекты." ] }, { "cell_type": "code", "metadata": { "id": "QlkGiSjxeSX3", "colab": { "base_uri": "https://localhost:8080/" }, "outputId": "d3033b84-8d2a-4e30-c937-29e910038622" }, "source": [ "a[1] = 3\n", "print(a)" ], "execution_count": 13, "outputs": [ { "output_type": "stream", "text": [ "[0 3 1]\n" ], "name": "stdout" } ] }, { "cell_type": "markdown", "metadata": { "id": "Yd31-o_UeSX6" }, "source": [ "Массивы, разумеется, можно использовать в `for` циклах. Но при этом теряется главное преимущество `numpy` — быстродействие. Всегда, когда это возможно, лучше использовать операции над массивами как едиными целыми." ] }, { "cell_type": "code", "metadata": { "id": "c4K_PK_OeSX7", "colab": { "base_uri": "https://localhost:8080/" }, "outputId": "f9203056-39fe-42c1-ffd7-88250a3d44c5" }, "source": [ "for i in a:\n", " print(i)" ], "execution_count": 14, "outputs": [ { "output_type": "stream", "text": [ "0\n", "3\n", "1\n" ], "name": "stdout" } ] }, { "cell_type": "markdown", "metadata": { "id": "SKlWqaBOe0hu" }, "source": [ "**Упражнение:** создайте numpy-массив, состоящий из первых пяти простых чисел, выведите его тип и размер.\n", "\n", "**Решение:**" ] }, { "cell_type": "code", "metadata": { "id": "fNmCAqpHe0hu", "colab": { "base_uri": "https://localhost:8080/" }, "outputId": "1aa6cf65-955e-4418-caa6-2a601e5d6a7d" }, "source": [ "arr = np.array([2, 3, 5, 7, 11])\n", "print(arr)\n", "print(arr.shape)\n", "print(arr.dtype)" ], "execution_count": 15, "outputs": [ { "output_type": "stream", "text": [ "[ 2 3 5 7 11]\n", "(5,)\n", "int64\n" ], "name": "stdout" } ] }, { "cell_type": "markdown", "metadata": { "id": "ViI6VqnXeSYE" }, "source": [ "#### 1.3 Создание массивов\n", "\n", "Массивы, заполненные нулями или единицами. Часто лучше сначала создать такой массив, а потом присваивать значения его элементам." ] }, { "cell_type": "code", "metadata": { "id": "V8yK0FLteSYF", "colab": { "base_uri": "https://localhost:8080/" }, "outputId": "c153fc22-1135-4374-c173-501ae407737e" }, "source": [ "a = np.zeros(3)\n", "b = np.ones(3, dtype=np.int64)\n", "print(a)\n", "print(b)" ], "execution_count": 16, "outputs": [ { "output_type": "stream", "text": [ "[0. 0. 0.]\n", "[1 1 1]\n" ], "name": "stdout" } ] }, { "cell_type": "markdown", "metadata": { "id": "YW31gGnbeSYI" }, "source": [ "Если нужно создать массив, заполненный нулями, длины и типа другого массива, то можно использовать конструкцию" ] }, { "cell_type": "code", "metadata": { "id": "0IJVs0EmeSYJ", "colab": { "base_uri": "https://localhost:8080/" }, "outputId": "ade64536-1489-42d5-ab23-1c55dd781a64" }, "source": [ "np.zeros_like(b)" ], "execution_count": 17, "outputs": [ { "output_type": "execute_result", "data": { "text/plain": [ "array([0, 0, 0])" ] }, "metadata": { "tags": [] }, "execution_count": 17 } ] }, { "cell_type": "markdown", "metadata": { "id": "-nnOn0gNeSYL" }, "source": [ "Функция `arange` подобна `range`. Аргументы могут быть с плавающей точкой. Следует избегать ситуаций, когда *(конец-начало)/шаг* — целое число, потому что в этом случае включение последнего элемента зависит от ошибок округления. Лучше, чтобы конец диапазона был где-то посредине шага." ] }, { "cell_type": "code", "metadata": { "id": "gqTdkX18eSYL", "colab": { "base_uri": "https://localhost:8080/" }, "outputId": "226a40e7-48df-4824-9c6b-46bfc8782e48" }, "source": [ "a = np.arange(0, 9, 2)\n", "print(a)" ], "execution_count": 18, "outputs": [ { "output_type": "stream", "text": [ "[0 2 4 6 8]\n" ], "name": "stdout" } ] }, { "cell_type": "code", "metadata": { "id": "7pY-5MmweSYN", "colab": { "base_uri": "https://localhost:8080/" }, "outputId": "99eca369-8eee-48c7-e9dd-62d9658ae4f2" }, "source": [ "b = np.arange(0., 9, 2)\n", "print(b)" ], "execution_count": 19, "outputs": [ { "output_type": "stream", "text": [ "[0. 2. 4. 6. 8.]\n" ], "name": "stdout" } ] }, { "cell_type": "markdown", "metadata": { "id": "vgPAKPaqeSYP" }, "source": [ "Последовательности чисел с постоянным шагом можно также создавать функцией `linspace`. Начало и конец диапазона включаются; последний аргумент — число точек." ] }, { "cell_type": "code", "metadata": { "id": "l1ruNluSeSYP", "colab": { "base_uri": "https://localhost:8080/" }, "outputId": "fd92731d-40dd-4e99-b507-89c995a6c699" }, "source": [ "a = np.linspace(0, 8, 5)\n", "print(a)" ], "execution_count": 20, "outputs": [ { "output_type": "stream", "text": [ "[0. 2. 4. 6. 8.]\n" ], "name": "stdout" } ] }, { "cell_type": "markdown", "metadata": { "id": "jltjeFtTe0hw" }, "source": [ "**Упражнение:** создайте и выведите последовательность чисел от 10 до 20 с постоянным шагом, длина последовательности - 21.\n", "\n", "**Решение:**" ] }, { "cell_type": "code", "metadata": { "id": "LsDkI-1Ye0hw", "colab": { "base_uri": "https://localhost:8080/" }, "outputId": "b1751942-21f5-48c4-cabb-ad5b24c427fe" }, "source": [ "arr = np.linspace(10, 20, 21)\n", "print(arr)" ], "execution_count": 21, "outputs": [ { "output_type": "stream", "text": [ "[10. 10.5 11. 11.5 12. 12.5 13. 13.5 14. 14.5 15. 15.5 16. 16.5\n", " 17. 17.5 18. 18.5 19. 19.5 20. ]\n" ], "name": "stdout" } ] }, { "cell_type": "markdown", "metadata": { "id": "LLfyQPuqeSYR" }, "source": [ "Последовательность чисел с постоянным шагом по логарифмической шкале от $10^0$ до $10^1$." ] }, { "cell_type": "code", "metadata": { "id": "Njm5f_n1eSYR", "colab": { "base_uri": "https://localhost:8080/" }, "outputId": "af0ab300-27cf-438f-9957-d87412be3858" }, "source": [ "b = np.logspace(0, 1, 5)\n", "print(b)" ], "execution_count": 22, "outputs": [ { "output_type": "stream", "text": [ "[ 1. 1.77827941 3.16227766 5.62341325 10. ]\n" ], "name": "stdout" } ] }, { "cell_type": "markdown", "metadata": { "id": "3TniLu7deSYT" }, "source": [ "## 2. Операции над одномерными массивами\n", "\n", "#### 2.1 Математические операции\n", "\n", "Арифметические операции проводятся поэлементно." ] }, { "cell_type": "code", "metadata": { "id": "YO9T5FQUe0hx", "colab": { "base_uri": "https://localhost:8080/" }, "outputId": "2ba2fc4b-9eab-4fc5-dbd9-cb6382c5ff7c" }, "source": [ "a" ], "execution_count": 23, "outputs": [ { "output_type": "execute_result", "data": { "text/plain": [ "array([0., 2., 4., 6., 8.])" ] }, "metadata": { "tags": [] }, "execution_count": 23 } ] }, { "cell_type": "code", "metadata": { "id": "DbjzvqYne0hx", "colab": { "base_uri": "https://localhost:8080/" }, "outputId": "d2856efa-53e1-4d61-e742-58e9c44a1c28" }, "source": [ "b" ], "execution_count": 24, "outputs": [ { "output_type": "execute_result", "data": { "text/plain": [ "array([ 1. , 1.77827941, 3.16227766, 5.62341325, 10. ])" ] }, "metadata": { "tags": [] }, "execution_count": 24 } ] }, { "cell_type": "code", "metadata": { "id": "XgS7-Hv-eSYT", "colab": { "base_uri": "https://localhost:8080/" }, "outputId": "c5025b44-7408-452e-a381-7cced0be0ee7" }, "source": [ "print(a + b)" ], "execution_count": 25, "outputs": [ { "output_type": "stream", "text": [ "[ 1. 3.77827941 7.16227766 11.62341325 18. ]\n" ], "name": "stdout" } ] }, { "cell_type": "code", "metadata": { "id": "qGK2iCjieSYV", "colab": { "base_uri": "https://localhost:8080/" }, "outputId": "efd40848-f7e7-49c9-fef1-eabe1a98c495" }, "source": [ "print(a - b)" ], "execution_count": 26, "outputs": [ { "output_type": "stream", "text": [ "[-1. 0.22172059 0.83772234 0.37658675 -2. ]\n" ], "name": "stdout" } ] }, { "cell_type": "code", "metadata": { "id": "23KFrhXfeSYX", "colab": { "base_uri": "https://localhost:8080/" }, "outputId": "743164d1-502e-47f2-8700-51c190fb16ec" }, "source": [ "print(a * b)" ], "execution_count": 27, "outputs": [ { "output_type": "stream", "text": [ "[ 0. 3.55655882 12.64911064 33.74047951 80. ]\n" ], "name": "stdout" } ] }, { "cell_type": "code", "metadata": { "id": "wKYv1wzReSYY", "colab": { "base_uri": "https://localhost:8080/" }, "outputId": "60176a8e-f58d-4f6f-e18e-ff04fb9b2463" }, "source": [ "print(a / b)" ], "execution_count": 28, "outputs": [ { "output_type": "stream", "text": [ "[0. 1.12468265 1.26491106 1.06696765 0.8 ]\n" ], "name": "stdout" } ] }, { "cell_type": "code", "metadata": { "id": "rxgiLyK0eSYa", "colab": { "base_uri": "https://localhost:8080/" }, "outputId": "37fd3999-6e6a-488f-8ca8-d9d689847afe" }, "source": [ "print(a ** 2)" ], "execution_count": 29, "outputs": [ { "output_type": "stream", "text": [ "[ 0. 4. 16. 36. 64.]\n" ], "name": "stdout" } ] }, { "cell_type": "markdown", "metadata": { "id": "K8DiU43EeSYc" }, "source": [ "Когда операнды разных типов, они пиводятся к большему типу." ] }, { "cell_type": "code", "metadata": { "id": "e3zsPgHweSYc", "colab": { "base_uri": "https://localhost:8080/" }, "outputId": "2416a590-8429-4072-f3a6-ea97eaaa6098" }, "source": [ "i = np.ones(5, dtype=np.int64)\n", "print(a + i)" ], "execution_count": 30, "outputs": [ { "output_type": "stream", "text": [ "[1. 3. 5. 7. 9.]\n" ], "name": "stdout" } ] }, { "cell_type": "markdown", "metadata": { "id": "Hy161lcoeSYd" }, "source": [ "Библиотека `numpy` содержит элементарные функции, которые тоже применяются к массивам поэлементно. Они называются универсальными функциями (`ufunc`)." ] }, { "cell_type": "code", "metadata": { "id": "Dkh0NdmyeSYe", "colab": { "base_uri": "https://localhost:8080/" }, "outputId": "7207bdc5-4078-4e9c-9bce-67a2ebfa7aa1" }, "source": [ "np.sin, type(np.sin)" ], "execution_count": 31, "outputs": [ { "output_type": "execute_result", "data": { "text/plain": [ "(, numpy.ufunc)" ] }, "metadata": { "tags": [] }, "execution_count": 31 } ] }, { "cell_type": "code", "metadata": { "id": "H5IHOdzVeSYf", "colab": { "base_uri": "https://localhost:8080/" }, "outputId": "b8719386-dced-47ea-b84a-d7c783742df0" }, "source": [ "print(np.sin(a))" ], "execution_count": 32, "outputs": [ { "output_type": "stream", "text": [ "[ 0. 0.90929743 -0.7568025 -0.2794155 0.98935825]\n" ], "name": "stdout" } ] }, { "cell_type": "markdown", "metadata": { "id": "Cm7c1VILeSYh" }, "source": [ "Один из операндов может быть скаляром, а не массивом." ] }, { "cell_type": "code", "metadata": { "id": "Wz9kCm0feSYh", "colab": { "base_uri": "https://localhost:8080/" }, "outputId": "69cbc3dd-ecc4-4fa7-f0b3-04500314197c" }, "source": [ "print(a + 1)" ], "execution_count": 33, "outputs": [ { "output_type": "stream", "text": [ "[1. 3. 5. 7. 9.]\n" ], "name": "stdout" } ] }, { "cell_type": "code", "metadata": { "id": "FeacFeQYeSYi", "colab": { "base_uri": "https://localhost:8080/" }, "outputId": "fd8b8697-7ff5-4f00-a314-b4407fd5bb46" }, "source": [ "print(2 * a)" ], "execution_count": 34, "outputs": [ { "output_type": "stream", "text": [ "[ 0. 4. 8. 12. 16.]\n" ], "name": "stdout" } ] }, { "cell_type": "markdown", "metadata": { "id": "76IhU9CAeSYk" }, "source": [ "Сравнения дают булевы массивы." ] }, { "cell_type": "code", "metadata": { "id": "69vVqzSgeSYk", "colab": { "base_uri": "https://localhost:8080/" }, "outputId": "3b573a73-d43a-49d5-ec93-d1d16bf5fceb" }, "source": [ "print(a > b)" ], "execution_count": 35, "outputs": [ { "output_type": "stream", "text": [ "[False True True True False]\n" ], "name": "stdout" } ] }, { "cell_type": "code", "metadata": { "id": "DwDMZFhSeSYl", "colab": { "base_uri": "https://localhost:8080/" }, "outputId": "81751830-d79b-4465-d604-9c61c4c5921b" }, "source": [ "print(a == b)" ], "execution_count": 36, "outputs": [ { "output_type": "stream", "text": [ "[False False False False False]\n" ], "name": "stdout" } ] }, { "cell_type": "code", "metadata": { "id": "TbjPskMceSYm", "colab": { "base_uri": "https://localhost:8080/" }, "outputId": "cd53b103-74f5-45a6-d1b1-415b3dd34577" }, "source": [ "c = a > 5\n", "print(c)" ], "execution_count": 37, "outputs": [ { "output_type": "stream", "text": [ "[False False False True True]\n" ], "name": "stdout" } ] }, { "cell_type": "markdown", "metadata": { "id": "vQ05bHN4eSYo" }, "source": [ "Кванторы \"существует\" и \"для всех\"." ] }, { "cell_type": "code", "metadata": { "id": "HTMkK7wYeSYo", "colab": { "base_uri": "https://localhost:8080/" }, "outputId": "3a0c7bfd-337c-4d11-c64b-738c0afee004" }, "source": [ "np.any(c), np.all(c)" ], "execution_count": 38, "outputs": [ { "output_type": "execute_result", "data": { "text/plain": [ "(True, False)" ] }, "metadata": { "tags": [] }, "execution_count": 38 } ] }, { "cell_type": "markdown", "metadata": { "id": "YdXbXq--eSYp" }, "source": [ "Модификация на месте." ] }, { "cell_type": "code", "metadata": { "id": "brP3tijHe0h4", "colab": { "base_uri": "https://localhost:8080/" }, "outputId": "25bff306-1ed7-460e-e024-4864917b4f75" }, "source": [ "a" ], "execution_count": 39, "outputs": [ { "output_type": "execute_result", "data": { "text/plain": [ "array([0., 2., 4., 6., 8.])" ] }, "metadata": { "tags": [] }, "execution_count": 39 } ] }, { "cell_type": "code", "metadata": { "id": "iNT_nYSveSYq", "colab": { "base_uri": "https://localhost:8080/" }, "outputId": "36888b15-4aec-43fa-c786-a1ed767af861" }, "source": [ "a += 1\n", "print(a)" ], "execution_count": 40, "outputs": [ { "output_type": "stream", "text": [ "[1. 3. 5. 7. 9.]\n" ], "name": "stdout" } ] }, { "cell_type": "code", "metadata": { "id": "g73lzOzKe0h4", "colab": { "base_uri": "https://localhost:8080/" }, "outputId": "22eb662b-4e46-4e10-990f-46211bbb2deb" }, "source": [ "b" ], "execution_count": 41, "outputs": [ { "output_type": "execute_result", "data": { "text/plain": [ "array([ 1. , 1.77827941, 3.16227766, 5.62341325, 10. ])" ] }, "metadata": { "tags": [] }, "execution_count": 41 } ] }, { "cell_type": "code", "metadata": { "id": "CItC6JrLeSYr", "colab": { "base_uri": "https://localhost:8080/" }, "outputId": "630f7c90-e654-47cc-8fb4-40624fe7b231" }, "source": [ "b *= 2\n", "print(b)" ], "execution_count": 42, "outputs": [ { "output_type": "stream", "text": [ "[ 2. 3.55655882 6.32455532 11.2468265 20. ]\n" ], "name": "stdout" } ] }, { "cell_type": "code", "metadata": { "id": "immEdJpGeSYt", "colab": { "base_uri": "https://localhost:8080/" }, "outputId": "b85467be-8135-4846-fc02-45a81bd64a4a" }, "source": [ "b /= a\n", "print(b)" ], "execution_count": 43, "outputs": [ { "output_type": "stream", "text": [ "[2. 1.18551961 1.26491106 1.6066895 2.22222222]\n" ], "name": "stdout" } ] }, { "cell_type": "markdown", "metadata": { "id": "JtiaPtiGeSYu" }, "source": [ "При выполнении операций над массивами деление на 0 не возбуждает исключения, а даёт значения `np.nan` или `np.inf`." ] }, { "cell_type": "code", "metadata": { "id": "uksiTX96eSYu", "colab": { "base_uri": "https://localhost:8080/" }, "outputId": "bc24c3c3-1e2e-4080-9886-443e1050ac1f" }, "source": [ "print(np.array([0.0, 0.0, 1.0, -1.0]) / np.array([1.0, 0.0, 0.0, 0.0]))" ], "execution_count": 44, "outputs": [ { "output_type": "stream", "text": [ "[ 0. nan inf -inf]\n" ], "name": "stdout" }, { "output_type": "stream", "text": [ "/usr/local/lib/python3.6/dist-packages/ipykernel_launcher.py:1: RuntimeWarning: divide by zero encountered in true_divide\n", " \"\"\"Entry point for launching an IPython kernel.\n", "/usr/local/lib/python3.6/dist-packages/ipykernel_launcher.py:1: RuntimeWarning: invalid value encountered in true_divide\n", " \"\"\"Entry point for launching an IPython kernel.\n" ], "name": "stderr" } ] }, { "cell_type": "code", "metadata": { "id": "sXwqQVDHeSYw", "colab": { "base_uri": "https://localhost:8080/" }, "outputId": "f5066abe-7676-4104-c599-cd20d670b898" }, "source": [ "np.nan + 1, np.inf + 1, np.inf * 0, 1. / np.inf" ], "execution_count": 45, "outputs": [ { "output_type": "execute_result", "data": { "text/plain": [ "(nan, inf, nan, 0.0)" ] }, "metadata": { "tags": [] }, "execution_count": 45 } ] }, { "cell_type": "markdown", "metadata": { "id": "ukM-LTuAeSYx" }, "source": [ "Сумма и произведение всех элементов массива; максимальный и минимальный элемент; среднее и среднеквадратичное отклонение." ] }, { "cell_type": "code", "metadata": { "id": "JP9gKcSTe0h5", "colab": { "base_uri": "https://localhost:8080/" }, "outputId": "f28c7262-600f-42de-e552-9ae857192a49" }, "source": [ "b" ], "execution_count": 46, "outputs": [ { "output_type": "execute_result", "data": { "text/plain": [ "array([2. , 1.18551961, 1.26491106, 1.6066895 , 2.22222222])" ] }, "metadata": { "tags": [] }, "execution_count": 46 } ] }, { "cell_type": "code", "metadata": { "id": "ZIo9nEFCeSYx", "colab": { "base_uri": "https://localhost:8080/" }, "outputId": "474d1790-16db-49ac-8c80-dba0d184de4c" }, "source": [ "b.sum(), b.prod(), b.max(), b.min(), b.mean(), b.std()" ], "execution_count": 47, "outputs": [ { "output_type": "execute_result", "data": { "text/plain": [ "(8.279342393526044,\n", " 10.708241812210389,\n", " 2.2222222222222223,\n", " 1.1855196066926152,\n", " 1.6558684787052087,\n", " 0.4039003342660745)" ] }, "metadata": { "tags": [] }, "execution_count": 47 } ] }, { "cell_type": "markdown", "metadata": { "id": "rju3ggwJeSYy" }, "source": [ "Имеются встроенные функции" ] }, { "cell_type": "code", "metadata": { "id": "H3xDbf6PeSYz", "colab": { "base_uri": "https://localhost:8080/" }, "outputId": "5392db56-b9be-48d3-d755-70d3677c1907" }, "source": [ "print(np.sqrt(b))\n", "print(np.exp(b))\n", "print(np.log(b))\n", "print(np.sin(b))\n", "print(np.e, np.pi)" ], "execution_count": 48, "outputs": [ { "output_type": "stream", "text": [ "[1.41421356 1.08881569 1.12468265 1.26755256 1.49071198]\n", "[7.3890561 3.27238673 3.54277764 4.98627681 9.22781435]\n", "[0.69314718 0.17018117 0.23500181 0.47417585 0.7985077 ]\n", "[0.90929743 0.92669447 0.95358074 0.99935591 0.79522006]\n", "2.718281828459045 3.141592653589793\n" ], "name": "stdout" } ] }, { "cell_type": "markdown", "metadata": { "id": "g6EBDaBWeSY0" }, "source": [ "Иногда бывает нужно использовать частичные (кумулятивные) суммы. В наших курсах такое может пригодится." ] }, { "cell_type": "code", "metadata": { "id": "JzFVH5DIeSY0", "colab": { "base_uri": "https://localhost:8080/" }, "outputId": "dfcab409-1ccf-46b1-f45e-97da0b8ea843" }, "source": [ "print(b.cumsum())" ], "execution_count": 49, "outputs": [ { "output_type": "stream", "text": [ "[2. 3.18551961 4.45043067 6.05712017 8.27934239]\n" ], "name": "stdout" } ] }, { "cell_type": "markdown", "metadata": { "id": "dyaDa9YXeSY1" }, "source": [ "#### 2.2 Сортировка, изменение массивов\n", "\n", "Функция `sort` возвращает отсортированную копию, метод `sort` сортирует на месте." ] }, { "cell_type": "code", "metadata": { "id": "i7Lw_nane0h6", "colab": { "base_uri": "https://localhost:8080/" }, "outputId": "942c058f-84df-4143-9594-4b4b873077bf" }, "source": [ "b" ], "execution_count": 50, "outputs": [ { "output_type": "execute_result", "data": { "text/plain": [ "array([2. , 1.18551961, 1.26491106, 1.6066895 , 2.22222222])" ] }, "metadata": { "tags": [] }, "execution_count": 50 } ] }, { "cell_type": "code", "metadata": { "id": "XS7IRW09eSY2", "colab": { "base_uri": "https://localhost:8080/" }, "outputId": "f29e931b-35cf-4f0a-ff8f-ea88322b1767" }, "source": [ "print(np.sort(b))\n", "print(b)" ], "execution_count": 51, "outputs": [ { "output_type": "stream", "text": [ "[1.18551961 1.26491106 1.6066895 2. 2.22222222]\n", "[2. 1.18551961 1.26491106 1.6066895 2.22222222]\n" ], "name": "stdout" } ] }, { "cell_type": "code", "metadata": { "id": "QENzFihJeSY3", "colab": { "base_uri": "https://localhost:8080/" }, "outputId": "a6486667-54b6-4ee7-9865-cff9a19a8b67" }, "source": [ "b.sort()\n", "print(b)" ], "execution_count": 52, "outputs": [ { "output_type": "stream", "text": [ "[1.18551961 1.26491106 1.6066895 2. 2.22222222]\n" ], "name": "stdout" } ] }, { "cell_type": "markdown", "metadata": { "id": "ZPjBXM_OeSY4" }, "source": [ "Объединение массивов." ] }, { "cell_type": "code", "metadata": { "id": "plNqd9H6e0h7", "colab": { "base_uri": "https://localhost:8080/" }, "outputId": "fc67e668-25ef-4bea-96a5-dc152ebf7476" }, "source": [ "a" ], "execution_count": 53, "outputs": [ { "output_type": "execute_result", "data": { "text/plain": [ "array([1., 3., 5., 7., 9.])" ] }, "metadata": { "tags": [] }, "execution_count": 53 } ] }, { "cell_type": "code", "metadata": { "id": "ZaD7r1qAe0h7", "colab": { "base_uri": "https://localhost:8080/" }, "outputId": "3422430f-6919-4776-ad2b-e476ed0aa31b" }, "source": [ "b" ], "execution_count": 54, "outputs": [ { "output_type": "execute_result", "data": { "text/plain": [ "array([1.18551961, 1.26491106, 1.6066895 , 2. , 2.22222222])" ] }, "metadata": { "tags": [] }, "execution_count": 54 } ] }, { "cell_type": "code", "metadata": { "id": "_SYn0MdseSY4", "colab": { "base_uri": "https://localhost:8080/" }, "outputId": "15209bdc-fc80-48fe-af8f-2d6897f242d5" }, "source": [ "a = np.hstack((a, b))\n", "print(a)" ], "execution_count": 55, "outputs": [ { "output_type": "stream", "text": [ "[1. 3. 5. 7. 9. 1.18551961\n", " 1.26491106 1.6066895 2. 2.22222222]\n" ], "name": "stdout" } ] }, { "cell_type": "markdown", "metadata": { "id": "cT0JM6lZeSY6" }, "source": [ "Расщепление массива в позициях 3 и 6." ] }, { "cell_type": "code", "metadata": { "id": "-DVwnZhFeSY6", "colab": { "base_uri": "https://localhost:8080/" }, "outputId": "c2133600-1ae5-4137-ec15-21355e8e27ba" }, "source": [ "np.hsplit(a, [3, 6])" ], "execution_count": 56, "outputs": [ { "output_type": "execute_result", "data": { "text/plain": [ "[array([1., 3., 5.]),\n", " array([7. , 9. , 1.18551961]),\n", " array([1.26491106, 1.6066895 , 2. , 2.22222222])]" ] }, "metadata": { "tags": [] }, "execution_count": 56 } ] }, { "cell_type": "markdown", "metadata": { "id": "eOZAGZV0eSY7" }, "source": [ "Функции `delete`, `insert` и `append` не меняют массив на месте, а возвращают новый массив, в котором удалены, вставлены в середину или добавлены в конец какие-то элементы." ] }, { "cell_type": "code", "metadata": { "id": "G4iDI8hjeSY8", "colab": { "base_uri": "https://localhost:8080/" }, "outputId": "a6a67121-a714-4ad4-c92d-35b174f945ac" }, "source": [ "a = np.delete(a, [5, 7])\n", "print(a)" ], "execution_count": 57, "outputs": [ { "output_type": "stream", "text": [ "[1. 3. 5. 7. 9. 1.26491106\n", " 2. 2.22222222]\n" ], "name": "stdout" } ] }, { "cell_type": "code", "metadata": { "id": "y2FW3FAYeSY9", "colab": { "base_uri": "https://localhost:8080/" }, "outputId": "3cf3226d-3f67-4c7e-b209-1effa27f6a45" }, "source": [ "a = np.insert(a, 2, [0, 0])\n", "print(a)" ], "execution_count": 58, "outputs": [ { "output_type": "stream", "text": [ "[1. 3. 0. 0. 5. 7.\n", " 9. 1.26491106 2. 2.22222222]\n" ], "name": "stdout" } ] }, { "cell_type": "code", "metadata": { "id": "DK6c68IxeSY-", "colab": { "base_uri": "https://localhost:8080/" }, "outputId": "c554e3fa-0efa-4708-97f9-ba4c48bc0ea5" }, "source": [ "a = np.append(a, [1, 2, 3])\n", "print(a)" ], "execution_count": 59, "outputs": [ { "output_type": "stream", "text": [ "[1. 3. 0. 0. 5. 7.\n", " 9. 1.26491106 2. 2.22222222 1. 2.\n", " 3. ]\n" ], "name": "stdout" } ] }, { "cell_type": "markdown", "metadata": { "id": "q669pBe0eSY_" }, "source": [ "#### 2.3 Способы индексации массивов\n", "\n", "Есть несколько способов индексации массива. Вот обычный индекс." ] }, { "cell_type": "code", "metadata": { "id": "oW8SgWFLeSZA", "colab": { "base_uri": "https://localhost:8080/" }, "outputId": "0789d77a-32aa-4030-ce34-8c474e8508e6" }, "source": [ "a = np.linspace(0, 1, 11)\n", "print(a)" ], "execution_count": 60, "outputs": [ { "output_type": "stream", "text": [ "[0. 0.1 0.2 0.3 0.4 0.5 0.6 0.7 0.8 0.9 1. ]\n" ], "name": "stdout" } ] }, { "cell_type": "code", "metadata": { "id": "7eQ_xryueSZB", "colab": { "base_uri": "https://localhost:8080/" }, "outputId": "4dea5038-cc90-4e23-8d54-9aa923e69e48" }, "source": [ "b = a[2]\n", "print(b)" ], "execution_count": 61, "outputs": [ { "output_type": "stream", "text": [ "0.2\n" ], "name": "stdout" } ] }, { "cell_type": "markdown", "metadata": { "id": "corcUOljeSZC" }, "source": [ "Диапазон индексов. Создаётся новый заголовок массива, указывающий на те же данные. Изменения, сделанные через такой массив, видны и в исходном массиве." ] }, { "cell_type": "code", "metadata": { "id": "g7sRF3GqeSZC", "colab": { "base_uri": "https://localhost:8080/" }, "outputId": "e0f7128d-af9d-4057-9678-afa1dff76ebf" }, "source": [ "b = a[2:6]\n", "print(b)" ], "execution_count": 62, "outputs": [ { "output_type": "stream", "text": [ "[0.2 0.3 0.4 0.5]\n" ], "name": "stdout" } ] }, { "cell_type": "code", "metadata": { "id": "mNJoJFFOeSZE", "colab": { "base_uri": "https://localhost:8080/" }, "outputId": "da9b8fd2-3fdd-4168-fcfc-5faeeaa6a4b8" }, "source": [ "b[0] = -0.2\n", "print(b)" ], "execution_count": 63, "outputs": [ { "output_type": "stream", "text": [ "[-0.2 0.3 0.4 0.5]\n" ], "name": "stdout" } ] }, { "cell_type": "code", "metadata": { "id": "PdAUJK9XeSZF", "colab": { "base_uri": "https://localhost:8080/" }, "outputId": "95510c3c-92c7-4657-ca7b-11b78b606735" }, "source": [ "print(a)" ], "execution_count": 64, "outputs": [ { "output_type": "stream", "text": [ "[ 0. 0.1 -0.2 0.3 0.4 0.5 0.6 0.7 0.8 0.9 1. ]\n" ], "name": "stdout" } ] }, { "cell_type": "markdown", "metadata": { "id": "lE9gziSweSZG" }, "source": [ "Диапазон с шагом 2." ] }, { "cell_type": "code", "metadata": { "id": "wLEQPJsXeSZH", "colab": { "base_uri": "https://localhost:8080/" }, "outputId": "70b6d2d5-10a3-4179-f130-19205e5985e4" }, "source": [ "b = a[1:10:2]\n", "print(b)" ], "execution_count": 65, "outputs": [ { "output_type": "stream", "text": [ "[0.1 0.3 0.5 0.7 0.9]\n" ], "name": "stdout" } ] }, { "cell_type": "code", "metadata": { "id": "Lw1rqM8WeSZI", "colab": { "base_uri": "https://localhost:8080/" }, "outputId": "23e8ca0a-c017-4822-f056-c541996585ee" }, "source": [ "b[0] = -0.1\n", "print(a)" ], "execution_count": 66, "outputs": [ { "output_type": "stream", "text": [ "[ 0. -0.1 -0.2 0.3 0.4 0.5 0.6 0.7 0.8 0.9 1. ]\n" ], "name": "stdout" } ] }, { "cell_type": "markdown", "metadata": { "id": "Nh9e4ZWNeSZK" }, "source": [ "Массив в обратном порядке." ] }, { "cell_type": "code", "metadata": { "id": "LKbKi90neSZK", "colab": { "base_uri": "https://localhost:8080/" }, "outputId": "76c81f57-4340-459f-d68a-76225dfb8bfd" }, "source": [ "b = a[::-1]\n", "print(b)" ], "execution_count": 67, "outputs": [ { "output_type": "stream", "text": [ "[ 1. 0.9 0.8 0.7 0.6 0.5 0.4 0.3 -0.2 -0.1 0. ]\n" ], "name": "stdout" } ] }, { "cell_type": "markdown", "metadata": { "id": "Im8dqbkIeSZL" }, "source": [ "Подмассиву можно присвоить значение — массив правильного размера или скаляр." ] }, { "cell_type": "code", "metadata": { "id": "cwQlTL-deSZM", "colab": { "base_uri": "https://localhost:8080/" }, "outputId": "bb149c0b-062b-4aae-dbb0-ff8ec5bf0f39" }, "source": [ "a[1:10:3] = 0\n", "print(a)" ], "execution_count": 68, "outputs": [ { "output_type": "stream", "text": [ "[ 0. 0. -0.2 0.3 0. 0.5 0.6 0. 0.8 0.9 1. ]\n" ], "name": "stdout" } ] }, { "cell_type": "markdown", "metadata": { "id": "NkDtCWUgeSZN" }, "source": [ "Тут опять создаётся только новый заголовок, указывающий на те же данные." ] }, { "cell_type": "code", "metadata": { "id": "BSI6oafVeSZO", "colab": { "base_uri": "https://localhost:8080/" }, "outputId": "a58398c1-0115-44c4-9d0a-f3b240351b50" }, "source": [ "b = a[:]\n", "b[1] = 0.1\n", "print(a)" ], "execution_count": 69, "outputs": [ { "output_type": "stream", "text": [ "[ 0. 0.1 -0.2 0.3 0. 0.5 0.6 0. 0.8 0.9 1. ]\n" ], "name": "stdout" } ] }, { "cell_type": "markdown", "metadata": { "id": "Zjq__bNXeSZP" }, "source": [ "Чтобы скопировать и данные массива, нужно использовать метод `copy`." ] }, { "cell_type": "code", "metadata": { "id": "VVds6EI5eSZP", "colab": { "base_uri": "https://localhost:8080/" }, "outputId": "117d2576-fbdb-470f-a6ed-63867824df1b" }, "source": [ "b = a.copy()\n", "b[2] = 0\n", "print(b)\n", "print(a)" ], "execution_count": 70, "outputs": [ { "output_type": "stream", "text": [ "[0. 0.1 0. 0.3 0. 0.5 0.6 0. 0.8 0.9 1. ]\n", "[ 0. 0.1 -0.2 0.3 0. 0.5 0.6 0. 0.8 0.9 1. ]\n" ], "name": "stdout" } ] }, { "cell_type": "markdown", "metadata": { "id": "2ynzvLTmeSZR" }, "source": [ "Можно задать список индексов." ] }, { "cell_type": "code", "metadata": { "id": "fRF4VWZmeSZR", "colab": { "base_uri": "https://localhost:8080/" }, "outputId": "be1a8534-35e2-4cbb-b94d-e2197ae290ae" }, "source": [ "print(a[[2, 3, 5]])" ], "execution_count": 71, "outputs": [ { "output_type": "stream", "text": [ "[-0.2 0.3 0.5]\n" ], "name": "stdout" } ] }, { "cell_type": "markdown", "metadata": { "id": "JF2kGGHDeSZT" }, "source": [ "Можно задать булев массив той же величины." ] }, { "cell_type": "code", "metadata": { "id": "yeFzrHxfeSZT", "colab": { "base_uri": "https://localhost:8080/" }, "outputId": "db7e6bd6-85c3-4643-f9ea-0256c994f0cf" }, "source": [ "b = a > 0\n", "print(b)" ], "execution_count": 72, "outputs": [ { "output_type": "stream", "text": [ "[False True False True False True True False True True True]\n" ], "name": "stdout" } ] }, { "cell_type": "code", "metadata": { "id": "CS_Xass1eSZU", "colab": { "base_uri": "https://localhost:8080/" }, "outputId": "e539153d-410e-4522-b24e-b0fce9b86c53" }, "source": [ "print(a[b])" ], "execution_count": 73, "outputs": [ { "output_type": "stream", "text": [ "[0.1 0.3 0.5 0.6 0.8 0.9 1. ]\n" ], "name": "stdout" } ] }, { "cell_type": "code", "metadata": { "id": "yvc9keete0iA", "colab": { "base_uri": "https://localhost:8080/" }, "outputId": "dcbf38c5-6970-4092-c78d-58966030074c" }, "source": [ "a" ], "execution_count": 74, "outputs": [ { "output_type": "execute_result", "data": { "text/plain": [ "array([ 0. , 0.1, -0.2, 0.3, 0. , 0.5, 0.6, 0. , 0.8, 0.9, 1. ])" ] }, "metadata": { "tags": [] }, "execution_count": 74 } ] }, { "cell_type": "code", "metadata": { "id": "G9i7pl7Ue0iB", "colab": { "base_uri": "https://localhost:8080/" }, "outputId": "9f24ff85-40e3-4b0c-e0ad-5b9f1fa1692f" }, "source": [ "b" ], "execution_count": 75, "outputs": [ { "output_type": "execute_result", "data": { "text/plain": [ "array([False, True, False, True, False, True, True, False, True,\n", " True, True])" ] }, "metadata": { "tags": [] }, "execution_count": 75 } ] }, { "cell_type": "markdown", "metadata": { "id": "HesCvUkKe0iB" }, "source": [ "**Упражнение:** \n", "1). Создайте массив чисел от $-2\\pi$ до $2\\pi$.\n", "\n", "2). Посчитайте сумму поэлементных квадратов синуса и косинуса для данного массива.\n", "\n", "3). С помощью `np.all` проверьте, что в ответе только единицы.\n", "\n", "**Решение:**" ] }, { "cell_type": "code", "metadata": { "id": "P9X8TP-ze0iB", "colab": { "base_uri": "https://localhost:8080/" }, "outputId": "16f49869-e858-4355-fa7f-7da36e9d52af" }, "source": [ "x = np.linspace(-2 * np.pi, 2 * np.pi, 20)\n", "np.all((np.sin(x)**2 + np.cos(x)**2).round() == 1)" ], "execution_count": 76, "outputs": [ { "output_type": "execute_result", "data": { "text/plain": [ "True" ] }, "metadata": { "tags": [] }, "execution_count": 76 } ] }, { "cell_type": "markdown", "metadata": { "id": "DUBkecfkeSZW" }, "source": [ "## 3. Двумерные массивы\n", "\n", "#### 3.1 Создание, простые операции" ] }, { "cell_type": "code", "metadata": { "id": "kELaHm5YeSZW", "colab": { "base_uri": "https://localhost:8080/" }, "outputId": "3cd3e31f-6680-4c40-9e14-1f58dc0691ba" }, "source": [ "a = np.array([[0.0, 1.0], [-1.0, 0.0]])\n", "print(a)" ], "execution_count": 77, "outputs": [ { "output_type": "stream", "text": [ "[[ 0. 1.]\n", " [-1. 0.]]\n" ], "name": "stdout" } ] }, { "cell_type": "code", "metadata": { "id": "py9Ei8aSeSZX", "colab": { "base_uri": "https://localhost:8080/" }, "outputId": "f87114fa-ec8a-4529-b7fc-0bac3fc9f6c5" }, "source": [ "a.ndim" ], "execution_count": 78, "outputs": [ { "output_type": "execute_result", "data": { "text/plain": [ "2" ] }, "metadata": { "tags": [] }, "execution_count": 78 } ] }, { "cell_type": "code", "metadata": { "id": "0TUKspWjeSZZ", "colab": { "base_uri": "https://localhost:8080/" }, "outputId": "943b099c-9f4c-4259-9537-01a1b7383258" }, "source": [ "a.shape" ], "execution_count": 79, "outputs": [ { "output_type": "execute_result", "data": { "text/plain": [ "(2, 2)" ] }, "metadata": { "tags": [] }, "execution_count": 79 } ] }, { "cell_type": "code", "metadata": { "id": "mH7fe1FkeSZa", "colab": { "base_uri": "https://localhost:8080/" }, "outputId": "b7d7aa81-ccd6-4c5e-ab80-c1152719e102" }, "source": [ "len(a), a.size" ], "execution_count": 80, "outputs": [ { "output_type": "execute_result", "data": { "text/plain": [ "(2, 4)" ] }, "metadata": { "tags": [] }, "execution_count": 80 } ] }, { "cell_type": "code", "metadata": { "id": "fYbyOh3geSZc", "colab": { "base_uri": "https://localhost:8080/" }, "outputId": "64081440-7325-4aa1-8f41-b7da16016d22" }, "source": [ "a[1, 0]" ], "execution_count": 81, "outputs": [ { "output_type": "execute_result", "data": { "text/plain": [ "-1.0" ] }, "metadata": { "tags": [] }, "execution_count": 81 } ] }, { "cell_type": "markdown", "metadata": { "id": "WaoO-VOLeSZd" }, "source": [ "Атрибуту `shape` можно присвоить новое значение — кортеж размеров по всем координатам. Получится новый заголовок массива; его данные не изменятся." ] }, { "cell_type": "code", "metadata": { "id": "Ht7CInofeSZe", "colab": { "base_uri": "https://localhost:8080/" }, "outputId": "252df4c7-898f-4216-c938-660923145f26" }, "source": [ "b = np.linspace(0, 3, 4)\n", "print(b)" ], "execution_count": 82, "outputs": [ { "output_type": "stream", "text": [ "[0. 1. 2. 3.]\n" ], "name": "stdout" } ] }, { "cell_type": "code", "metadata": { "id": "LmOZ33breSZf", "colab": { "base_uri": "https://localhost:8080/" }, "outputId": "af9d14e5-61a9-481a-9600-8fe0584f747f" }, "source": [ "b.shape" ], "execution_count": 83, "outputs": [ { "output_type": "execute_result", "data": { "text/plain": [ "(4,)" ] }, "metadata": { "tags": [] }, "execution_count": 83 } ] }, { "cell_type": "code", "metadata": { "id": "_TYvZX8eeSZg", "colab": { "base_uri": "https://localhost:8080/" }, "outputId": "265ec86b-5bb0-412e-8991-59d02fe3d00b" }, "source": [ "b.shape = 2, 2\n", "print(b)" ], "execution_count": 84, "outputs": [ { "output_type": "stream", "text": [ "[[0. 1.]\n", " [2. 3.]]\n" ], "name": "stdout" } ] }, { "cell_type": "markdown", "metadata": { "id": "jWVJLH9ZeSZh" }, "source": [ "Можно растянуть в одномерный массив" ] }, { "cell_type": "code", "metadata": { "id": "aJdF4hyreSZi", "colab": { "base_uri": "https://localhost:8080/" }, "outputId": "da04abfc-c815-4e32-d234-665462e8e4e4" }, "source": [ "print(b.ravel())" ], "execution_count": 85, "outputs": [ { "output_type": "stream", "text": [ "[0. 1. 2. 3.]\n" ], "name": "stdout" } ] }, { "cell_type": "markdown", "metadata": { "id": "ff31TTeHeSZj" }, "source": [ "Арифметические операции поэлементные" ] }, { "cell_type": "code", "metadata": { "id": "a6WXKEj4eSZj", "colab": { "base_uri": "https://localhost:8080/" }, "outputId": "d699628b-8e06-4072-fcc9-1b8f9d851974" }, "source": [ "print(a + 1)\n", "print(a * 2)\n", "print(a + [0, 1]) # второе слагаемое дополняется до матрицы копированием строк\n", "print(a + np.array([[0, 2]]).T) # .T - транспонирование\n", "print(a + b)" ], "execution_count": 86, "outputs": [ { "output_type": "stream", "text": [ "[[1. 2.]\n", " [0. 1.]]\n", "[[ 0. 2.]\n", " [-2. 0.]]\n", "[[ 0. 2.]\n", " [-1. 1.]]\n", "[[0. 1.]\n", " [1. 2.]]\n", "[[0. 2.]\n", " [1. 3.]]\n" ], "name": "stdout" } ] }, { "cell_type": "markdown", "metadata": { "id": "nLIlrz-BeSZl" }, "source": [ "#### 3.2 Работа с матрицами\n", "\n", "Поэлементное и матричное (только в Python >=3.5) умножение." ] }, { "cell_type": "code", "metadata": { "id": "xAUzdffSeSZl", "colab": { "base_uri": "https://localhost:8080/" }, "outputId": "85839d49-25fe-4488-c545-b1ef585242e0" }, "source": [ "print(a * b)" ], "execution_count": 87, "outputs": [ { "output_type": "stream", "text": [ "[[ 0. 1.]\n", " [-2. 0.]]\n" ], "name": "stdout" } ] }, { "cell_type": "code", "metadata": { "id": "GAI2uX5PeSZn", "colab": { "base_uri": "https://localhost:8080/" }, "outputId": "a3dde70a-fcfd-4ef6-e729-410a141ed591" }, "source": [ "print(a @ b)" ], "execution_count": 88, "outputs": [ { "output_type": "stream", "text": [ "[[ 2. 3.]\n", " [ 0. -1.]]\n" ], "name": "stdout" } ] }, { "cell_type": "code", "metadata": { "id": "6ERS9kXLeSZp", "colab": { "base_uri": "https://localhost:8080/" }, "outputId": "f06e0cc2-dd98-421b-c1d8-84ac01244c43" }, "source": [ "print(b @ a)" ], "execution_count": 89, "outputs": [ { "output_type": "stream", "text": [ "[[-1. 0.]\n", " [-3. 2.]]\n" ], "name": "stdout" } ] }, { "cell_type": "markdown", "metadata": { "id": "KiDTXGnge0iF" }, "source": [ "**Упражнение:** создайте матрицы $\\begin{pmatrix} -3 & 4 \\\\ 4 & 3 \\end{pmatrix}$ и $\\begin{pmatrix} 2 & 1 \\\\ 1 & 2 \\end{pmatrix}$. Посчитайте их поэлементное и матричное произведения.\n", "\n", "**Решение:**" ] }, { "cell_type": "code", "metadata": { "id": "Ct4fsUQwe0iF", "colab": { "base_uri": "https://localhost:8080/" }, "outputId": "78dc1ad4-95c1-4094-ac95-21c7b22be9d1" }, "source": [ "a = np.array([[-3, 4], [4, 3]])\n", "b = np.array([[2, 1], [1, 2]])\n", "print(a * b)\n", "print(b * a)\n", "print(a @ b)\n", "print(b @ a)" ], "execution_count": 90, "outputs": [ { "output_type": "stream", "text": [ "[[-6 4]\n", " [ 4 6]]\n", "[[-6 4]\n", " [ 4 6]]\n", "[[-2 5]\n", " [11 10]]\n", "[[-2 11]\n", " [ 5 10]]\n" ], "name": "stdout" } ] }, { "cell_type": "markdown", "metadata": { "id": "-3Wm4rIieSZ3" }, "source": [ "Умножение матрицы на вектор." ] }, { "cell_type": "code", "metadata": { "id": "mXgY1mBoeSZ4", "colab": { "base_uri": "https://localhost:8080/" }, "outputId": "e67dcdb3-a128-4336-fa28-625de78e08aa" }, "source": [ "v = np.array([1, -1], dtype=np.float64)\n", "print(b @ v)" ], "execution_count": 91, "outputs": [ { "output_type": "stream", "text": [ "[ 1. -1.]\n" ], "name": "stdout" } ] }, { "cell_type": "code", "metadata": { "id": "A0Emfd5ueSZ5", "colab": { "base_uri": "https://localhost:8080/" }, "outputId": "02a0d2e9-a771-49cd-bc8b-58733db360a6" }, "source": [ "print(v @ b)" ], "execution_count": 92, "outputs": [ { "output_type": "stream", "text": [ "[ 1. -1.]\n" ], "name": "stdout" } ] }, { "cell_type": "markdown", "metadata": { "id": "uJp4qRrOeSZ6" }, "source": [ "Если у вас Питон более ранней версии, то для работы с матрицами можно использовать класс `np.matrix`, в котором операция умножения реализуется как матричное умножение." ] }, { "cell_type": "code", "metadata": { "id": "a84Su-DneSZ6", "colab": { "base_uri": "https://localhost:8080/" }, "outputId": "99c0d192-3955-40b7-af6e-f98498a29e08" }, "source": [ "np.matrix(a) * np.matrix(b)" ], "execution_count": 93, "outputs": [ { "output_type": "execute_result", "data": { "text/plain": [ "matrix([[-2, 5],\n", " [11, 10]])" ] }, "metadata": { "tags": [] }, "execution_count": 93 } ] }, { "cell_type": "markdown", "metadata": { "id": "ttfS-0_GeSZ7" }, "source": [ "Внешнее произведение $a_{ij}=u_i v_j$" ] }, { "cell_type": "code", "metadata": { "id": "hzr6tlLdeSZ8", "colab": { "base_uri": "https://localhost:8080/" }, "outputId": "cd0f3318-ed6d-40d7-815b-97f34091d418" }, "source": [ "u = np.linspace(1, 2, 2)\n", "v = np.linspace(2, 4, 3)\n", "print(u)\n", "print(v)" ], "execution_count": 94, "outputs": [ { "output_type": "stream", "text": [ "[1. 2.]\n", "[2. 3. 4.]\n" ], "name": "stdout" } ] }, { "cell_type": "code", "metadata": { "id": "FcsJmsiGeSZ9", "colab": { "base_uri": "https://localhost:8080/" }, "outputId": "559ee87d-bdc0-48f9-fc09-48c4f1a74eb1" }, "source": [ "a = np.outer(u, v)\n", "print(a)" ], "execution_count": 95, "outputs": [ { "output_type": "stream", "text": [ "[[2. 3. 4.]\n", " [4. 6. 8.]]\n" ], "name": "stdout" } ] }, { "cell_type": "markdown", "metadata": { "id": "Aa_dWlyveSZ-" }, "source": [ "Двумерные массивы, зависящие только от одного индекса: $x_{ij}=u_j$, $y_{ij}=v_i$" ] }, { "cell_type": "code", "metadata": { "id": "4i6zYBg9eSZ_", "colab": { "base_uri": "https://localhost:8080/" }, "outputId": "68cc1973-8ff6-4283-da0b-f35e292b3c47" }, "source": [ "x, y = np.meshgrid(u, v)\n", "print(x)\n", "print(y)" ], "execution_count": 96, "outputs": [ { "output_type": "stream", "text": [ "[[1. 2.]\n", " [1. 2.]\n", " [1. 2.]]\n", "[[2. 2.]\n", " [3. 3.]\n", " [4. 4.]]\n" ], "name": "stdout" } ] }, { "cell_type": "markdown", "metadata": { "id": "KwK4g9gZeSaA" }, "source": [ "Единичная матрица." ] }, { "cell_type": "code", "metadata": { "id": "ST8KOHBWeSaB", "colab": { "base_uri": "https://localhost:8080/" }, "outputId": "8d31c952-a08b-40f9-b04b-b749b1ccb3d1" }, "source": [ "I = np.eye(4)\n", "print(I)" ], "execution_count": 97, "outputs": [ { "output_type": "stream", "text": [ "[[1. 0. 0. 0.]\n", " [0. 1. 0. 0.]\n", " [0. 0. 1. 0.]\n", " [0. 0. 0. 1.]]\n" ], "name": "stdout" } ] }, { "cell_type": "markdown", "metadata": { "id": "zDOuMhIzeSaC" }, "source": [ "Метод `reshape` делает то же самое, что присваивание атрибуту `shape`." ] }, { "cell_type": "code", "metadata": { "id": "iV0R_x39eSaC", "colab": { "base_uri": "https://localhost:8080/" }, "outputId": "ea5ca4be-b5e3-4454-db78-7bbcc9edf2c1" }, "source": [ "print(I.reshape(16))" ], "execution_count": 98, "outputs": [ { "output_type": "stream", "text": [ "[1. 0. 0. 0. 0. 1. 0. 0. 0. 0. 1. 0. 0. 0. 0. 1.]\n" ], "name": "stdout" } ] }, { "cell_type": "code", "metadata": { "id": "uIEi4h1MeSaD", "colab": { "base_uri": "https://localhost:8080/" }, "outputId": "60147a79-67ea-4fc2-c612-7d776486e185" }, "source": [ "print(I.reshape(2, 8))" ], "execution_count": 99, "outputs": [ { "output_type": "stream", "text": [ "[[1. 0. 0. 0. 0. 1. 0. 0.]\n", " [0. 0. 1. 0. 0. 0. 0. 1.]]\n" ], "name": "stdout" } ] }, { "cell_type": "markdown", "metadata": { "id": "HfQZjZZleSaE" }, "source": [ "Строка." ] }, { "cell_type": "code", "metadata": { "id": "dU-B5CsdeSaE", "colab": { "base_uri": "https://localhost:8080/" }, "outputId": "3a79b4a9-a664-435b-f984-97b21c606bc9" }, "source": [ "print(I[1])" ], "execution_count": 100, "outputs": [ { "output_type": "stream", "text": [ "[0. 1. 0. 0.]\n" ], "name": "stdout" } ] }, { "cell_type": "markdown", "metadata": { "id": "ptRot99NeSaF" }, "source": [ "Цикл по строкам." ] }, { "cell_type": "code", "metadata": { "id": "CQ3h7yA0eSaG", "colab": { "base_uri": "https://localhost:8080/" }, "outputId": "c6a78675-1314-4dab-8c01-6ced6e408d9e" }, "source": [ "for row in I:\n", " print(row)" ], "execution_count": 101, "outputs": [ { "output_type": "stream", "text": [ "[1. 0. 0. 0.]\n", "[0. 1. 0. 0.]\n", "[0. 0. 1. 0.]\n", "[0. 0. 0. 1.]\n" ], "name": "stdout" } ] }, { "cell_type": "markdown", "metadata": { "id": "V6lshMkHeSaH" }, "source": [ "Столбец." ] }, { "cell_type": "code", "metadata": { "id": "orbMt6WMeSaH", "colab": { "base_uri": "https://localhost:8080/" }, "outputId": "eb7a3b85-79ed-474b-ae59-5e5eb51d8aef" }, "source": [ "print(I[:, 2])" ], "execution_count": 102, "outputs": [ { "output_type": "stream", "text": [ "[0. 0. 1. 0.]\n" ], "name": "stdout" } ] }, { "cell_type": "markdown", "metadata": { "id": "nqnUtI-SeSaI" }, "source": [ "Подматрица." ] }, { "cell_type": "code", "metadata": { "id": "p8ycTAw3eSaI", "colab": { "base_uri": "https://localhost:8080/" }, "outputId": "a40adbbc-717f-44ea-8e14-ebccb0658383" }, "source": [ "print(I[0:2, 1:3])" ], "execution_count": 103, "outputs": [ { "output_type": "stream", "text": [ "[[0. 0.]\n", " [1. 0.]]\n" ], "name": "stdout" } ] }, { "cell_type": "markdown", "metadata": { "id": "wDDkZc3WeSaJ" }, "source": [ "Можно построить двумерный массив из функции." ] }, { "cell_type": "code", "metadata": { "id": "KXCnqDLKeSaK", "colab": { "base_uri": "https://localhost:8080/" }, "outputId": "25a6b5dd-ed62-498d-a67b-09d2c4a34e21" }, "source": [ "def f(i, j):\n", " print(i)\n", " print(j)\n", " return 10 * i + j\n", "\n", "print(np.fromfunction(f, (4, 4), dtype=np.int64))" ], "execution_count": 104, "outputs": [ { "output_type": "stream", "text": [ "[[0 0 0 0]\n", " [1 1 1 1]\n", " [2 2 2 2]\n", " [3 3 3 3]]\n", "[[0 1 2 3]\n", " [0 1 2 3]\n", " [0 1 2 3]\n", " [0 1 2 3]]\n", "[[ 0 1 2 3]\n", " [10 11 12 13]\n", " [20 21 22 23]\n", " [30 31 32 33]]\n" ], "name": "stdout" } ] }, { "cell_type": "markdown", "metadata": { "id": "OFz0xwrreSaL" }, "source": [ "Транспонированная матрица." ] }, { "cell_type": "code", "metadata": { "id": "Z4J5zzvNeSaL", "colab": { "base_uri": "https://localhost:8080/" }, "outputId": "2be97c2c-10ca-44ca-e8ad-607029d46253" }, "source": [ "print(b.T)" ], "execution_count": 105, "outputs": [ { "output_type": "stream", "text": [ "[[2 1]\n", " [1 2]]\n" ], "name": "stdout" } ] }, { "cell_type": "markdown", "metadata": { "id": "yGeRknu3eSaM" }, "source": [ "Соединение матриц по горизонтали и по вертикали." ] }, { "cell_type": "code", "metadata": { "id": "ObH0A6B3eSaM", "colab": { "base_uri": "https://localhost:8080/" }, "outputId": "64e093bf-8da3-4c2c-819f-10b4227caf39" }, "source": [ "a = np.array([[0, 1], [2, 3]])\n", "b = np.array([[4, 5, 6], [7, 8, 9]])\n", "c = np.array([[4, 5], [6, 7], [8, 9]])\n", "print(a)\n", "print(b)\n", "print(c)" ], "execution_count": 106, "outputs": [ { "output_type": "stream", "text": [ "[[0 1]\n", " [2 3]]\n", "[[4 5 6]\n", " [7 8 9]]\n", "[[4 5]\n", " [6 7]\n", " [8 9]]\n" ], "name": "stdout" } ] }, { "cell_type": "code", "metadata": { "id": "0cpapPNveSaN", "colab": { "base_uri": "https://localhost:8080/" }, "outputId": "c1438798-7f39-4b85-c06a-1ba673e4aa8c" }, "source": [ "print(np.hstack((a, b)))" ], "execution_count": 107, "outputs": [ { "output_type": "stream", "text": [ "[[0 1 4 5 6]\n", " [2 3 7 8 9]]\n" ], "name": "stdout" } ] }, { "cell_type": "code", "metadata": { "id": "EPxXHWTAeSaO", "colab": { "base_uri": "https://localhost:8080/" }, "outputId": "5913d8bc-92e1-4f4c-a093-88b06a0b7e36" }, "source": [ "print(np.vstack((a, c)))" ], "execution_count": 108, "outputs": [ { "output_type": "stream", "text": [ "[[0 1]\n", " [2 3]\n", " [4 5]\n", " [6 7]\n", " [8 9]]\n" ], "name": "stdout" } ] }, { "cell_type": "markdown", "metadata": { "id": "i3SBcbGzeSaP" }, "source": [ "Сумма всех элементов; суммы столбцов; суммы строк." ] }, { "cell_type": "code", "metadata": { "id": "V4Mgz9GIe0iL", "colab": { "base_uri": "https://localhost:8080/" }, "outputId": "7fcc2f63-d8e4-4895-8294-b1c750ecb896" }, "source": [ "b" ], "execution_count": 109, "outputs": [ { "output_type": "execute_result", "data": { "text/plain": [ "array([[4, 5, 6],\n", " [7, 8, 9]])" ] }, "metadata": { "tags": [] }, "execution_count": 109 } ] }, { "cell_type": "code", "metadata": { "id": "kQLBs3mHeSaP", "colab": { "base_uri": "https://localhost:8080/" }, "outputId": "7bc9cf66-69d5-4ef6-dd75-1fd906796fbd" }, "source": [ "print(b.sum())\n", "print(b.sum(axis=0))\n", "print(b.sum(axis=1))" ], "execution_count": 110, "outputs": [ { "output_type": "stream", "text": [ "39\n", "[11 13 15]\n", "[15 24]\n" ], "name": "stdout" } ] }, { "cell_type": "markdown", "metadata": { "id": "rc8otaIBeSaQ" }, "source": [ "Аналогично работают `prod`, `max`, `min` и т.д." ] }, { "cell_type": "code", "metadata": { "id": "822so2-9eSaQ", "colab": { "base_uri": "https://localhost:8080/" }, "outputId": "bcfe87f2-ce52-43c5-8f34-9739acfe367b" }, "source": [ "print(b.max())\n", "print(b.max(axis=0))\n", "print(b.min(axis=1))" ], "execution_count": 111, "outputs": [ { "output_type": "stream", "text": [ "9\n", "[7 8 9]\n", "[4 7]\n" ], "name": "stdout" } ] }, { "cell_type": "markdown", "metadata": { "id": "AlzAeJI-eSaR" }, "source": [ "След - сумма диагональных элементов." ] }, { "cell_type": "code", "metadata": { "id": "-BlaKobheSaR", "colab": { "base_uri": "https://localhost:8080/" }, "outputId": "17e826d4-378a-4c0d-b5fa-9d4d13373510" }, "source": [ "np.trace(a)" ], "execution_count": 112, "outputs": [ { "output_type": "execute_result", "data": { "text/plain": [ "3" ] }, "metadata": { "tags": [] }, "execution_count": 112 } ] }, { "cell_type": "markdown", "metadata": { "id": "nAr4Sa4Te0iM" }, "source": [ "**Упражнение:** \n", "\n", "в статистике и машинном обучении часто приходится иметь с функцией $RSS$, которая вычисляется по формуле $\\sum_{i=1}^{n} (y_i - a_i)^2$, где $y_i$ — координаты одномерного вектора $y$, $a_i$ — координаты одномерного вектора $a$. Посчитайте $RSS$ для $y = (1, 2, 3, 4, 5), a = (3, 2, 1, 0, -1)$.\n", "\n", "**Решение:**" ] }, { "cell_type": "code", "metadata": { "id": "wdiG3YHQe0iM" }, "source": [ "# решение\n", "y = np.arange(1, 6)\n", "a = np.arange(3, -2, -1)\n", "rss = np.sum((y - a)**2)" ], "execution_count": 113, "outputs": [] }, { "cell_type": "markdown", "metadata": { "id": "7VULr5jSeSaS" }, "source": [ "## 4. Тензоры (многомерные массивы)" ] }, { "cell_type": "markdown", "metadata": { "id": "3wwvC1UOQppZ" }, "source": [ "#### 4.1 Создание, простые операции" ] }, { "cell_type": "code", "metadata": { "id": "_Vx6sZvjeSaT", "colab": { "base_uri": "https://localhost:8080/" }, "outputId": "7a541976-019e-410c-a112-999c2d2bbc5a" }, "source": [ "X = np.arange(24).reshape(2, 3, 4)\n", "print(X)" ], "execution_count": 114, "outputs": [ { "output_type": "stream", "text": [ "[[[ 0 1 2 3]\n", " [ 4 5 6 7]\n", " [ 8 9 10 11]]\n", "\n", " [[12 13 14 15]\n", " [16 17 18 19]\n", " [20 21 22 23]]]\n" ], "name": "stdout" } ] }, { "cell_type": "markdown", "metadata": { "id": "6-a_IMz5eSaU" }, "source": [ "Суммирование (аналогично остальные операции)" ] }, { "cell_type": "code", "metadata": { "id": "XnTt-275eSaU", "colab": { "base_uri": "https://localhost:8080/" }, "outputId": "c9e9da8e-5415-4a22-cadf-5c95bebe3933" }, "source": [ "# суммируем только по нулевой оси, то есть для фиксированных j и k \n", "# суммируем только элементы с индексами (*, j, k)\n", "print(X.sum(axis=0))" ], "execution_count": 115, "outputs": [ { "output_type": "stream", "text": [ "[[12 14 16 18]\n", " [20 22 24 26]\n", " [28 30 32 34]]\n" ], "name": "stdout" } ] }, { "cell_type": "code", "metadata": { "id": "O5m-SV4Ge0iN", "colab": { "base_uri": "https://localhost:8080/" }, "outputId": "e4b5e1a4-3ce0-41a1-d0de-dd23d9c299bb" }, "source": [ "# суммируем сразу по двум осям, то есть для фиксированной i \n", "# суммируем только элементы с индексами (i, *, *)\n", "print(X.sum(axis=(1, 2)))" ], "execution_count": 116, "outputs": [ { "output_type": "stream", "text": [ "[ 66 210]\n" ], "name": "stdout" } ] }, { "cell_type": "markdown", "metadata": { "id": "-FWPCnqzQppZ" }, "source": [ "#### 4.2. Broadcasting" ] }, { "cell_type": "markdown", "metadata": { "id": "uPjV3yjKQppZ" }, "source": [ "Выше при арифметических операциях с массивами, например, при сложении и умножении, мы перемножали массивы одинаковой формы. В самом простом случае операндами были одномерные массивы одинаковой длины." ] }, { "cell_type": "code", "metadata": { "id": "vjFxZY6JQppa", "colab": { "base_uri": "https://localhost:8080/" }, "outputId": "ace21081-8132-4348-d239-481dd0138cf3" }, "source": [ "# Самый простой случай\n", "a = np.array([1, 2, 3])\n", "b = np.array([2, 2, 2])\n", "print(a * b)" ], "execution_count": 117, "outputs": [ { "output_type": "stream", "text": [ "[2 4 6]\n" ], "name": "stdout" } ] }, { "cell_type": "markdown", "metadata": { "id": "CFUBi7CDQppa" }, "source": [ "Произошло поэлементное умножение, все элементы массива $a$ умножились на $2$. Но мы знаем, что это можно сделать проще, просто умножив массив на $2$." ] }, { "cell_type": "code", "metadata": { "id": "eSGmLzA5Qppa", "colab": { "base_uri": "https://localhost:8080/" }, "outputId": "efbee6ec-4cbe-4990-a676-638dc754bd8b" }, "source": [ "# Умножение массива на число\n", "print(a * 2)" ], "execution_count": 118, "outputs": [ { "output_type": "stream", "text": [ "[2 4 6]\n" ], "name": "stdout" } ] }, { "cell_type": "markdown", "metadata": { "id": "u7_r9j_9Qppb" }, "source": [ "На самом деле поведение будет аналогичным, если умножить одномерный массив на массив длины $1$." ] }, { "cell_type": "code", "metadata": { "id": "yg6006goQppb", "colab": { "base_uri": "https://localhost:8080/" }, "outputId": "c6bd4f17-4b6b-4c03-bd6a-c9e947e03ec0" }, "source": [ "# Умножение массивов разных длин\n", "print(a * [2])" ], "execution_count": 119, "outputs": [ { "output_type": "stream", "text": [ "[2 4 6]\n" ], "name": "stdout" } ] }, { "cell_type": "markdown", "metadata": { "id": "FoaMvoBmQppc" }, "source": [ "В этом случае работает так называемый *broadcasting*. Один массив \"растягивается\", чтобы повторить форму другого.\n", "\n", "![theory.broadcast_1.gif](data:image/gif;base64,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)" ] }, { "cell_type": "markdown", "metadata": { "id": "vzmLw9c3Qppc" }, "source": [ "Такой же эффект работает и для многомерных массивов. Если по какому-то измерению размер у одного массива равен $1$, а у другого — произвольный, то по этому измерению может произойти \"рястяжение\". Таким образом, массивы можно умножать друг на друга, если в измерениях, где они по размеру не совпадают, хотя бы у одного размер $1$. Для других поэлементных операций правило аналогично.\n", "\n", "Важно отметить, что размерности сопоставляются справа налево. Если их количество не совпадает, что массивы меньшей размерности сначала дополняются слева размерностями 1. Например, при сложении массива размера $4 \\times 3$ с массивом размера $3$ последний сначала преобразуется в массив размера $1 \\times 3$." ] }, { "cell_type": "code", "metadata": { "id": "MPaw_M3iQppc", "colab": { "base_uri": "https://localhost:8080/" }, "outputId": "2b0d412d-ecc7-441d-a9f6-147c354cf72c" }, "source": [ "a = np.array([[ 0, 0, 0],\n", " [10, 10, 10],\n", " [20, 20, 20],\n", " [30, 30, 30]])\n", "\n", "b = np.array([0, 1, 2])\n", "\n", "print(a + b)" ], "execution_count": 120, "outputs": [ { "output_type": "stream", "text": [ "[[ 0 1 2]\n", " [10 11 12]\n", " [20 21 22]\n", " [30 31 32]]\n" ], "name": "stdout" } ] }, { "cell_type": "markdown", "metadata": { "id": "NVxT_nHjQppd" }, "source": [ "Схематично проведенную операцию можно визуализировать следующим образом.\n", "\n", "![theory.broadcast_2.gif](data:image/gif;base64,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)\n", "\n", "\n", "Если неединичные размерности справа не будут совпадать, то выполнить операцию уже не получится. Например, как приведено на схеме ниже. \n", "\n", "![theory.broadcast_3.gif](data:image/gif;base64,R0lGODlhbgH7AHcAMSH+GlNvZnR3YXJlOiBNaWNyb3NvZnQgT2ZmaWNlACH5BAEAAAAALAIADQBeAekAhgAAAAAAAAQHDA0LCAQECA0LCgcCAgcJDAIGCgQABAkLDAcCAA0JBgICBgsLDA0HBAAECAkEAAAABAkLCgAAAgsGAgACBgIABAIAAgQAAAsJCgIAAAQCBgQAAgIECAIEBAQHCAcGAg0JCAQEBgQHCgkJBgsLCAICAAAAKwAAVQArgABVqisAACsrACuA1FUAAFWAgFWq/4ArAICqgIDU1IDU/6pVAKqqVar/1Kr//9SAK8DAwNT///+qVf/UgP//qv//1P///wECAwECAwECAwECAwECAwECAwECAwECAwECAwECAwECAwECAwECAwECAwECAwECAwECAwECAwECAwECAwECAwECAwECAwECAwECAwECAwECAwECAwECAwECAwECAwECAwECAwECAwECAwECAwECAwECAwECAwECAwECAwECAwECAwECAwECAwECAwECAwECAwECAwECAwECAwECAwECAwECAwECAwECAwECAwECAwECAwECAwECAwECAwf/gACCg4SFhoeIiYqLjI2Oj5CRhRECkogDBIgFBgeWnp+goaKjpKWmp6ipjBEIlwkKqrGys7S1tre4jAULlYcMDQ65wsPExca0DxARARITC8ywyYLLARSdycvNzxKwANTcuwEBlQ/i4wDY1Z3H7O3u7+wV5xHW3pUVrQ8WwQ/c8pX0OlECUAHCNIMMLsCqwA0AAwwH/hFsBa+ixYsYQ7GaVmkXwEoDMjScRnGgRwAaBm2UFrKXyl4bM8qcSVPmpk43AQx4lVMQgw3gOAHIuRMWNXEAWyXsJihnz5pQo0rNNYBDsF9XgRXVF8xe1axguerscOCkWG8IsOp8NbWt27el/6ShMzjXoQeHG0BmECC3r0GxEbgNIDv2Gje5auEqXsxYET5BjydKRmeuVeTLrcIF+KAwZL1y0CZHbky6tOnTqFOrXs26tevXsGPLnk27tu3buHO3M8e7t+/fwIMLH068uPHjyJMrD6D7NfPmcJ9DXy19+tTq1k9jz15zO/fG3r9nDC8+enmo5M+3Ta/eHfv24wm9h5+r+nz6FqU/v49/ln5B/PXHzn4ABChgLAQaeKAxzDW44IAFRvhgd+JMOGCFFnaXIYQb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)\n" ] }, { "cell_type": "markdown", "metadata": { "id": "H_FZ39gJQppd" }, "source": [ "**Упражнение:**\n", "\n", "Подумайте, массив какого размера получится, если перемножить массив $4 \\times 1 \\times 3$ и массив $12 \\times 1$. Убедитесь на практике в правильности вашего ответа." ] }, { "cell_type": "code", "metadata": { "id": "4oVm6BevQppd", "colab": { "base_uri": "https://localhost:8080/" }, "outputId": "96379ebe-5510-4b58-fdaf-5fc0d4afb45a" }, "source": [ "# решение\n", "a = np.ones((4, 1, 3))\n", "b = np.ones((12, 1))\n", "\n", "mul_shape = (a * b).shape\n", "print(mul_shape)" ], "execution_count": 121, "outputs": [ { "output_type": "stream", "text": [ "(4, 12, 3)\n" ], "name": "stdout" } ] }, { "cell_type": "markdown", "metadata": { "id": "sWPEBlaKQppe" }, "source": [ "*Замечание*\n", "\n", "Знать про broadcasting нужно, но пользоваться им надо с осторожностью. Многократное копирование массива при растяжении может привести к неэффективной работе программы по памяти. Особенно за этим приходится следить при работе с GPU." ] }, { "cell_type": "markdown", "metadata": { "id": "fQu4JWrkeSaV" }, "source": [ "## 5. Линейная алгебра" ] }, { "cell_type": "code", "metadata": { "id": "KJ9qk8KBe0iO" }, "source": [ "a = np.array([[0, 1], [2, 3]])" ], "execution_count": 122, "outputs": [] }, { "cell_type": "code", "metadata": { "id": "QfoGKtHdeSaV", "colab": { "base_uri": "https://localhost:8080/" }, "outputId": "34c3e346-e206-42d8-d63e-a8df8ed5e244" }, "source": [ "np.linalg.det(a)" ], "execution_count": 123, "outputs": [ { "output_type": "execute_result", "data": { "text/plain": [ "-2.0" ] }, "metadata": { "tags": [] }, "execution_count": 123 } ] }, { "cell_type": "markdown", "metadata": { "id": "fh6WDlobeSaW" }, "source": [ "Обратная матрица." ] }, { "cell_type": "code", "metadata": { "id": "6_JMYc5NeSaX", "colab": { "base_uri": "https://localhost:8080/" }, "outputId": "9df6bde7-2001-43b3-820c-64838ee4d3a1" }, "source": [ "a1 = np.linalg.inv(a)\n", "print(a1)" ], "execution_count": 124, "outputs": [ { "output_type": "stream", "text": [ "[[-1.5 0.5]\n", " [ 1. 0. ]]\n" ], "name": "stdout" } ] }, { "cell_type": "code", "metadata": { "id": "9RK1Y8tOeSaY", "colab": { "base_uri": "https://localhost:8080/" }, "outputId": "16f5ad20-22d6-4d7b-91f6-2fc11ce38b65" }, "source": [ "print(a @ a1)\n", "print(a1 @ a)" ], "execution_count": 125, "outputs": [ { "output_type": "stream", "text": [ "[[1. 0.]\n", " [0. 1.]]\n", "[[1. 0.]\n", " [0. 1.]]\n" ], "name": "stdout" } ] }, { "cell_type": "markdown", "metadata": { "id": "hjrrv-DqeSaY" }, "source": [ "Решение линейной системы $au=v$." ] }, { "cell_type": "code", "metadata": { "id": "gXVo3PmCeSaZ", "colab": { "base_uri": "https://localhost:8080/" }, "outputId": "671b4b71-31ba-4cc4-bb11-c331f4bcfd8d" }, "source": [ "v = np.array([0, 1], dtype=np.float64)\n", "print(a1 @ v)" ], "execution_count": 126, "outputs": [ { "output_type": "stream", "text": [ "[0.5 0. ]\n" ], "name": "stdout" } ] }, { "cell_type": "code", "metadata": { "id": "CH5xU8hXeSaa", "colab": { "base_uri": "https://localhost:8080/" }, "outputId": "25a0e01a-db24-4f20-f8ff-1eefa06662b6" }, "source": [ "u = np.linalg.solve(a, v)\n", "print(u)" ], "execution_count": 127, "outputs": [ { "output_type": "stream", "text": [ "[0.5 0. ]\n" ], "name": "stdout" } ] }, { "cell_type": "markdown", "metadata": { "id": "n4Qrc4JCeSab" }, "source": [ "Проверим." ] }, { "cell_type": "code", "metadata": { "id": "FzmdANWPeSab", "colab": { "base_uri": "https://localhost:8080/" }, "outputId": "60425a1b-96d1-4acf-987f-49b215a6c66b" }, "source": [ "print(a @ u - v)" ], "execution_count": 128, "outputs": [ { "output_type": "stream", "text": [ "[0. 0.]\n" ], "name": "stdout" } ] }, { "cell_type": "markdown", "metadata": { "id": "nr9z4BbGeSac" }, "source": [ "Собственные значения и собственные векторы: $a u_i = \\lambda_i u_i$. `l` — одномерный массив собственных значений $\\lambda_i$, столбцы матрицы $u$ — собственные векторы $u_i$." ] }, { "cell_type": "code", "metadata": { "id": "0W3HKMpreSac", "colab": { "base_uri": "https://localhost:8080/" }, "outputId": "e187541e-0e99-4f23-ac7b-18bb5c9185ac" }, "source": [ "l, u = np.linalg.eig(a)\n", "print(l)" ], "execution_count": 129, "outputs": [ { "output_type": "stream", "text": [ "[-0.56155281 3.56155281]\n" ], "name": "stdout" } ] }, { "cell_type": "code", "metadata": { "id": "iDz1izeneSad", "colab": { "base_uri": "https://localhost:8080/" }, "outputId": "465c5027-2489-494a-a7a7-65c855360ddc" }, "source": [ "print(u)" ], "execution_count": 130, "outputs": [ { "output_type": "stream", "text": [ "[[-0.87192821 -0.27032301]\n", " [ 0.48963374 -0.96276969]]\n" ], "name": "stdout" } ] }, { "cell_type": "markdown", "metadata": { "id": "dNGJ88UCeSae" }, "source": [ "Проверим." ] }, { "cell_type": "code", "metadata": { "id": "OAbVlo3PeSae", "colab": { "base_uri": "https://localhost:8080/" }, "outputId": "988320e5-c8d4-4bdd-d73e-27ed4133d2d5" }, "source": [ "for i in range(2):\n", " print(a @ u[:, i] - l[i] * u[:, i])" ], "execution_count": 131, "outputs": [ { "output_type": "stream", "text": [ "[0.00000000e+00 1.66533454e-16]\n", "[ 0.0000000e+00 -4.4408921e-16]\n" ], "name": "stdout" } ] }, { "cell_type": "markdown", "metadata": { "id": "CTiDbQI_eSaf" }, "source": [ "Функция `diag` от одномерного массива строит диагональную матрицу; от квадратной матрицы — возвращает одномерный массив её диагональных элементов." ] }, { "cell_type": "code", "metadata": { "id": "gHJlMqRIeSag", "colab": { "base_uri": "https://localhost:8080/" }, "outputId": "b4159388-466a-4571-f7b9-fe808794f4c5" }, "source": [ "L = np.diag(l)\n", "print(L)\n", "print(np.diag(L))" ], "execution_count": 132, "outputs": [ { "output_type": "stream", "text": [ "[[-0.56155281 0. ]\n", " [ 0. 3.56155281]]\n", "[-0.56155281 3.56155281]\n" ], "name": "stdout" } ] }, { "cell_type": "markdown", "metadata": { "id": "tOKmUQDyeSah" }, "source": [ "Все уравнения $a u_i = \\lambda_i u_i$ можно собрать в одно матричное уравнение $a u = u \\Lambda$, где $\\Lambda$ — диагональная матрица с собственными значениями $\\lambda_i$ по диагонали." ] }, { "cell_type": "code", "metadata": { "id": "qXSUnhqweSah", "colab": { "base_uri": "https://localhost:8080/" }, "outputId": "86fcec2a-2785-4cd7-ed05-7d6cd0627fbb" }, "source": [ "print(a @ u - u @ L)" ], "execution_count": 133, "outputs": [ { "output_type": "stream", "text": [ "[[ 0.00000000e+00 0.00000000e+00]\n", " [ 1.66533454e-16 -4.44089210e-16]]\n" ], "name": "stdout" } ] }, { "cell_type": "markdown", "metadata": { "id": "b1vsNPo8eSai" }, "source": [ "Поэтому $u^{-1} a u = \\Lambda$." ] }, { "cell_type": "code", "metadata": { "id": "D8aJ2LeUeSai", "colab": { "base_uri": "https://localhost:8080/" }, "outputId": "c0037584-4a24-4ebf-c46f-1f5579bb89a3" }, "source": [ "print(np.linalg.inv(u) @ a @ u)" ], "execution_count": 134, "outputs": [ { "output_type": "stream", "text": [ "[[-5.61552813e-01 2.77555756e-17]\n", " [-2.22044605e-16 3.56155281e+00]]\n" ], "name": "stdout" } ] }, { "cell_type": "markdown", "metadata": { "id": "GDV31jreeSaj" }, "source": [ "Найдём теперь левые собственные векторы $v_i a = \\lambda_i v_i$. Собственные значения $\\lambda_i$ те же самые." ] }, { "cell_type": "code", "metadata": { "id": "1HyE2M51eSaj", "colab": { "base_uri": "https://localhost:8080/" }, "outputId": "3224d81d-0d24-41f7-8084-d35f5ec105ce" }, "source": [ "l, v = np.linalg.eig(a.T)\n", "print(l)\n", "print(v)" ], "execution_count": 135, "outputs": [ { "output_type": "stream", "text": [ "[-0.56155281 3.56155281]\n", "[[-0.96276969 -0.48963374]\n", " [ 0.27032301 -0.87192821]]\n" ], "name": "stdout" } ] }, { "cell_type": "markdown", "metadata": { "id": "kvTFZXzieSak" }, "source": [ "Собственные векторы нормированы на 1." ] }, { "cell_type": "code", "metadata": { "id": "mtRpa6CSeSak", "colab": { "base_uri": "https://localhost:8080/" }, "outputId": "2a828cf5-704f-4cfe-d294-f0a21cd67658" }, "source": [ "print(u.T @ u)\n", "print(v.T @ v)" ], "execution_count": 136, "outputs": [ { "output_type": "stream", "text": [ "[[ 1. -0.23570226]\n", " [-0.23570226 1. ]]\n", "[[1. 0.23570226]\n", " [0.23570226 1. ]]\n" ], "name": "stdout" } ] }, { "cell_type": "markdown", "metadata": { "id": "cF_vDIO0eSal" }, "source": [ "Левые и правые собственные векторы, соответствующие разным собственным значениям, ортогональны, потому что $v_i a u_j = \\lambda_i v_i u_j = \\lambda_j v_i u_j$." ] }, { "cell_type": "code", "metadata": { "id": "Ntj_buO3eSam", "colab": { "base_uri": "https://localhost:8080/" }, "outputId": "3af47be2-accb-4c9f-cad1-98e0f571ed5c" }, "source": [ "print(v.T @ u)" ], "execution_count": 137, "outputs": [ { "output_type": "stream", "text": [ "[[ 9.71825316e-01 0.00000000e+00]\n", " [-5.55111512e-17 9.71825316e-01]]\n" ], "name": "stdout" } ] }, { "cell_type": "markdown", "metadata": { "id": "UPo6GT9Ne0iU" }, "source": [ "**Упражнение:** \n", "\n", "в машинном обучении есть модель линейной регрессии, для которой \"хорошее\" решение считается по следующей формуле: $\\widehat{\\theta} = (X^T \\cdot X + \\lambda \\cdot I_n)^{-1}\\cdot X^T y$. Вычислите $\\widehat{\\theta}$ для $ X = \\begin{pmatrix} -3 & 4 & 1 \\\\ 4 & 3 & 1 \\end{pmatrix}$, $y = \\begin{pmatrix} 10 \\\\ 12 \\end{pmatrix}$, $I_n$ — единичная матрица размерности 3, $\\lambda = 0.1$.\n", "\n", "**Решение:**" ] }, { "cell_type": "code", "metadata": { "id": "WTHCzulBi1Jk" }, "source": [ "X = np.array([[-3, 4, 1], [4, 3, 1]])\n", "y = np.array([10, 12])\n", "I = np.eye(3)\n", "lambd = 0.1\n", "theta = np.linalg.inv(X.T @ X + lambd * I) @ X.T @ y" ], "execution_count": 138, "outputs": [] }, { "cell_type": "markdown", "metadata": { "id": "qw_8kCAIeSam" }, "source": [ "## 6. Интегрирование" ] }, { "cell_type": "code", "metadata": { "id": "3dA2vW9NeSan" }, "source": [ "from scipy.integrate import quad, odeint\n", "from scipy.special import erf" ], "execution_count": 139, "outputs": [] }, { "cell_type": "code", "metadata": { "id": "ZR_J8-LFeSao" }, "source": [ "def f(x):\n", " return np.exp(-x ** 2)" ], "execution_count": 140, "outputs": [] }, { "cell_type": "markdown", "metadata": { "id": "mC4waOCPeSao" }, "source": [ "Адаптивное численное интегрирование (может быть до бесконечности). `err` — оценка ошибки." ] }, { "cell_type": "code", "metadata": { "id": "ybR0uRuneSap", "colab": { "base_uri": "https://localhost:8080/" }, "outputId": "b54ae1b7-a5b0-4f02-a4a8-90c13d47aa45" }, "source": [ "res, err = quad(f, 0, np.inf)\n", "print(np.sqrt(np.pi) / 2, res, err)" ], "execution_count": 141, "outputs": [ { "output_type": "stream", "text": [ "0.8862269254527579 0.8862269254527579 7.101318390472462e-09\n" ], "name": "stdout" } ] }, { "cell_type": "code", "metadata": { "id": "-QGAB-m3eSaq", "colab": { "base_uri": "https://localhost:8080/" }, "outputId": "1ae84784-9295-4b6c-89c9-36d40143dc49" }, "source": [ "res, err = quad(f, 0, 1)\n", "print(np.sqrt(np.pi) / 2 * erf(1), res, err)" ], "execution_count": 142, "outputs": [ { "output_type": "stream", "text": [ "0.7468241328124269 0.7468241328124271 8.291413475940725e-15\n" ], "name": "stdout" } ] }, { "cell_type": "markdown", "metadata": { "id": "huwe8P9LeSaq" }, "source": [ "## 7. Сохранение в файл и чтение из файла" ] }, { "cell_type": "code", "metadata": { "id": "2XDE5GHzeSar" }, "source": [ "x = np.arange(0, 25, 0.5).reshape((5, 10))\n", "\n", "# Сохраняем в файл example.txt данные x в формате с двумя точками после запятой и разделителем ';'\n", "np.savetxt('example.txt', x, fmt='%.2f', delimiter=';')" ], "execution_count": 143, "outputs": [] }, { "cell_type": "markdown", "metadata": { "id": "B9RcBcSpeSas" }, "source": [ "Получится такой файл" ] }, { "cell_type": "code", "metadata": { "id": "dqoUbX3meSas", "colab": { "base_uri": "https://localhost:8080/" }, "outputId": "47d520e9-52d1-44ad-8391-abad741d8cd1" }, "source": [ "! cat example.txt" ], "execution_count": 144, "outputs": [ { "output_type": "stream", "text": [ "0.00;0.50;1.00;1.50;2.00;2.50;3.00;3.50;4.00;4.50\n", "5.00;5.50;6.00;6.50;7.00;7.50;8.00;8.50;9.00;9.50\n", "10.00;10.50;11.00;11.50;12.00;12.50;13.00;13.50;14.00;14.50\n", "15.00;15.50;16.00;16.50;17.00;17.50;18.00;18.50;19.00;19.50\n", "20.00;20.50;21.00;21.50;22.00;22.50;23.00;23.50;24.00;24.50\n" ], "name": "stdout" } ] }, { "cell_type": "markdown", "metadata": { "id": "EMfZ9-KceSat" }, "source": [ "Теперь его можно прочитать" ] }, { "cell_type": "code", "metadata": { "id": "AzLywGeKeSat", "colab": { "base_uri": "https://localhost:8080/" }, "outputId": "718c3f45-21bb-429b-e8e0-1e99d3dac43b" }, "source": [ "x = np.loadtxt('example.txt', delimiter=';')\n", "print(x)" ], "execution_count": 145, "outputs": [ { "output_type": "stream", "text": [ "[[ 0. 0.5 1. 1.5 2. 2.5 3. 3.5 4. 4.5]\n", " [ 5. 5.5 6. 6.5 7. 7.5 8. 8.5 9. 9.5]\n", " [10. 10.5 11. 11.5 12. 12.5 13. 13.5 14. 14.5]\n", " [15. 15.5 16. 16.5 17. 17.5 18. 18.5 19. 19.5]\n", " [20. 20.5 21. 21.5 22. 22.5 23. 23.5 24. 24.5]]\n" ], "name": "stdout" } ] }, { "cell_type": "markdown", "metadata": { "id": "Y4voLe-LeSau" }, "source": [ "## 8. Производительность numpy\n", "\n", "Посмотрим на простой пример — сумма первых $10^8$ чисел." ] }, { "cell_type": "code", "metadata": { "id": "nvCQ_4WReSav", "colab": { "base_uri": "https://localhost:8080/" }, "outputId": "7a346ff9-570e-4edf-cb2f-416a6d77c822" }, "source": [ "%%time\n", "\n", "sum_value = 0\n", "for i in range(10 ** 8):\n", " sum_value += i\n", "print(sum_value)" ], "execution_count": 146, "outputs": [ { "output_type": "stream", "text": [ "4999999950000000\n", "CPU times: user 11.5 s, sys: 10.3 ms, total: 11.5 s\n", "Wall time: 11.6 s\n" ], "name": "stdout" } ] }, { "cell_type": "markdown", "metadata": { "id": "v4SQIcy8eSaw" }, "source": [ "Немного улучшеный код" ] }, { "cell_type": "code", "metadata": { "id": "ewr9BFMpeSaw", "colab": { "base_uri": "https://localhost:8080/" }, "outputId": "9d95e4f0-3b2f-4fc0-d128-0b1d941d9601" }, "source": [ "%%time\n", "\n", "sum_value = sum(range(10 ** 8))\n", "print(sum_value)" ], "execution_count": 147, "outputs": [ { "output_type": "stream", "text": [ "4999999950000000\n", "CPU times: user 1.66 s, sys: 4.14 ms, total: 1.67 s\n", "Wall time: 1.67 s\n" ], "name": "stdout" } ] }, { "cell_type": "markdown", "metadata": { "id": "pUjiYs86eSax" }, "source": [ "Код с использованием функций библиотеки `numpy`" ] }, { "cell_type": "code", "metadata": { "id": "Jv6RFksoeSax", "colab": { "base_uri": "https://localhost:8080/" }, "outputId": "b4bd7af6-5da9-49d8-ea76-471c4190cb1e" }, "source": [ "%%time\n", "\n", "sum_value = np.arange(10 ** 8).sum()\n", "print(sum_value)" ], "execution_count": 148, "outputs": [ { "output_type": "stream", "text": [ "4999999950000000\n", "CPU times: user 170 ms, sys: 221 ms, total: 391 ms\n", "Wall time: 395 ms\n" ], "name": "stdout" } ] }, { "cell_type": "markdown", "metadata": { "id": "ya-V2P3veSay" }, "source": [ "Простой и понятный код работает в $30$ раз быстрее!\n", "\n", "Посмотрим на другой пример. Сгенерируем матрицу размера $500\\times1000$, и вычислим средний минимум по колонкам.\n", "\n", "Простой код, но при этом даже использующий некоторые питон-функции\n", "\n", "*Замечание*. Далее с помощью `scipy.stats` происходит генерация случайных чисел из равномерного распределения на отрезке $[0, 1]$. Этот модуль будем изучать в следующем ноутбуке." ] }, { "cell_type": "code", "metadata": { "id": "Ulfmy68keSaz" }, "source": [ "import scipy.stats as sps" ], "execution_count": 149, "outputs": [] }, { "cell_type": "code", "metadata": { "id": "bp_qnnwPeSaz", "colab": { "base_uri": "https://localhost:8080/" }, "outputId": "c8e6d324-5d1a-4b25-aefc-6270056ae3c5" }, "source": [ "%%time\n", "\n", "N, M = 500, 1000\n", "matrix = []\n", "for i in range(N):\n", " matrix.append([sps.uniform.rvs() for j in range(M)])\n", "\n", "min_col = [min([matrix[i][j] for i in range(N)]) for j in range(M)]\n", "mean_min = sum(min_col) / N\n", "print(mean_min)" ], "execution_count": 150, "outputs": [ { "output_type": "stream", "text": [ "0.003964031389280003\n", "CPU times: user 17.7 s, sys: 26.9 ms, total: 17.7 s\n", "Wall time: 17.7 s\n" ], "name": "stdout" } ] }, { "cell_type": "markdown", "metadata": { "id": "c47oHwHzeSa0" }, "source": [ "Понятный код с использованием функций библиотеки numpy" ] }, { "cell_type": "code", "metadata": { "id": "h1WGN9hseSa0", "colab": { "base_uri": "https://localhost:8080/" }, "outputId": "72ac21e2-9230-4b28-e30d-1a8c1356c69c" }, "source": [ "%%time\n", "\n", "N, M = 500, 1000\n", "matrix = sps.uniform.rvs(size=(N, M))\n", "mean_min = matrix.min(axis=1).mean()\n", "print(mean_min)" ], "execution_count": 151, "outputs": [ { "output_type": "stream", "text": [ "0.0010107557488341552\n", "CPU times: user 37.2 ms, sys: 2.98 ms, total: 40.1 ms\n", "Wall time: 40.3 ms\n" ], "name": "stdout" } ] }, { "cell_type": "markdown", "metadata": { "id": "ABVSxP6seSa1" }, "source": [ "Простой и понятный код работает в 1500 раз быстрее!" ] }, { "cell_type": "markdown", "metadata": { "id": "8X4QkUGIe0ib" }, "source": [ "## 9. Суммы Эйнштейна\n", "\n", "С помощью соглашения Эйнштейна о суммировании, многие общие многомерные линейные алгебраические операции с массивами могут быть представлены простым способом.\n", "\n", "`Если одна и та же буква в обозначении индекса встречается и сверху, и снизу, то такой член полагается просуммированным по всем значениям, которые может принимать этот индекс. `\n", "\n", "Например, выражение $c_j = a_i b^i_j$ понимается как $c_j = \\sum_{i=1}^n a_i b^i_j$.\n", "\n", "Подобные операции часто возникают в анализе данных, в особенности при реализации байесовских методов.\n", "\n", "В `numpy` такие операции реализует функция `einsum`, причем здесь не делается разницы между нижними и верхними индексами. Функция принимает на вход сигнатуру операции в виде текстовой строки и матрицы с данными.\n", "\n", "Разберем на примере выше. В данном случае сигнатура имеет вид `i,ji->j`. Элементы сигнатуры последовательно означают следующее (тензор = многомерная матрица):\n", "* `i`— объявление обозначений индексов тензора $A$. Поскольку индекс один, то тем самым $A$ должен быть вектором.\n", "* `,` — переход к объявлению индексов следующему тензору.\n", "* `ji` — объявление обозначений индексов тензора $B$. Поскольку индекса два, то тем самым $B$ должен быть матрицей.\n", "* `->` — разграничение входа и выхода.\n", "* `j` — индекс на выходе. Поскольку индекс $i$ объявлен на входе и не объявлен на выходе, по нему происходит суммирование поэлементных произведений." ] }, { "cell_type": "code", "metadata": { "id": "frEWaGTpe0ic", "colab": { "base_uri": "https://localhost:8080/" }, "outputId": "69d026fa-5beb-479a-97ad-7df9be8e37f1" }, "source": [ "A = np.array([0, 1, 2])\n", "B = np.array([[10, 15, 20], [100, 150, 200]])\n", "print(A)\n", "print(B)" ], "execution_count": 152, "outputs": [ { "output_type": "stream", "text": [ "[0 1 2]\n", "[[ 10 15 20]\n", " [100 150 200]]\n" ], "name": "stdout" } ] }, { "cell_type": "markdown", "metadata": { "id": "wnYXLx7me0ic" }, "source": [ "В приведенном выше примере получаем:\n", "* $c_0 = a_0 \\cdot b^0_0 + a_1 \\cdot b^1_0 + a_2 \\cdot b^2_0$. В нашем случае: $c_0 = 0 \\cdot 1 + 1 \\cdot 15 + 2 \\cdot 20$.\n", "* $c_1 = a_0 \\cdot b^0_1 + a_1 \\cdot b^1_1 + a_2 \\cdot b^2_1$. В нашем случае: $c_1 = 0 \\cdot 1 + 1 \\cdot 150 + 2 \\cdot 200$." ] }, { "cell_type": "code", "metadata": { "id": "kUOJs_Ppe0ic", "colab": { "base_uri": "https://localhost:8080/" }, "outputId": "a8082871-1a93-4357-faa3-8b36ead2f684" }, "source": [ "np.einsum('i,ji->j', A, B)" ], "execution_count": 153, "outputs": [ { "output_type": "execute_result", "data": { "text/plain": [ "array([ 55, 550])" ] }, "metadata": { "tags": [] }, "execution_count": 153 } ] }, { "cell_type": "markdown", "metadata": { "id": "QbMfu2t3e0ic" }, "source": [ "Суммирование элементов вектора $A$" ] }, { "cell_type": "code", "metadata": { "id": "f3mqdCsxe0ic", "colab": { "base_uri": "https://localhost:8080/" }, "outputId": "9d3623f2-327c-4683-e9f7-b5e48a49d807" }, "source": [ "np.einsum('i->', A)" ], "execution_count": 154, "outputs": [ { "output_type": "execute_result", "data": { "text/plain": [ "3" ] }, "metadata": { "tags": [] }, "execution_count": 154 } ] }, { "cell_type": "markdown", "metadata": { "id": "lRiHtZRJe0id" }, "source": [ "Суммирование элементов матрицы $B$ по столбцам" ] }, { "cell_type": "code", "metadata": { "id": "2FOx17B8e0id", "colab": { "base_uri": "https://localhost:8080/" }, "outputId": "b0c38c14-24b3-4dbe-c678-2ab7d1cb5dc9" }, "source": [ "np.einsum('ji->i', B)" ], "execution_count": 155, "outputs": [ { "output_type": "execute_result", "data": { "text/plain": [ "array([110, 165, 220])" ] }, "metadata": { "tags": [] }, "execution_count": 155 } ] }, { "cell_type": "markdown", "metadata": { "id": "NrhfL3pTe0id" }, "source": [ "Рассмотрим следующие матрицы" ] }, { "cell_type": "code", "metadata": { "id": "KGWiDJh6e0id", "colab": { "base_uri": "https://localhost:8080/" }, "outputId": "b40bbb19-eb61-46a4-cce0-dd78f621cbeb" }, "source": [ "A = np.array([[0, 1, 2], [3, 4, 5]])\n", "B = np.array([[0, 1], [10, 100], [30, 70]])\n", "print(A)\n", "print(B)" ], "execution_count": 156, "outputs": [ { "output_type": "stream", "text": [ "[[0 1 2]\n", " [3 4 5]]\n", "[[ 0 1]\n", " [ 10 100]\n", " [ 30 70]]\n" ], "name": "stdout" } ] }, { "cell_type": "markdown", "metadata": { "id": "_ZLBqQNne0id" }, "source": [ "Транспонирование матрицы $A$" ] }, { "cell_type": "code", "metadata": { "id": "7UejqaL3e0ie", "colab": { "base_uri": "https://localhost:8080/" }, "outputId": "fa0373d2-f657-45f4-abba-4a538febc9c2" }, "source": [ "np.einsum('ij->ji', A) " ], "execution_count": 157, "outputs": [ { "output_type": "execute_result", "data": { "text/plain": [ "array([[0, 3],\n", " [1, 4],\n", " [2, 5]])" ] }, "metadata": { "tags": [] }, "execution_count": 157 } ] }, { "cell_type": "markdown", "metadata": { "id": "aMhJgvvwe0ie" }, "source": [ "Матричное умножение" ] }, { "cell_type": "code", "metadata": { "id": "egjfsoYRe0ie", "colab": { "base_uri": "https://localhost:8080/" }, "outputId": "1fef7539-4fda-4330-c43b-7b7ca04b230c" }, "source": [ "np.einsum('ij,jk->ik', A, B) " ], "execution_count": 158, "outputs": [ { "output_type": "execute_result", "data": { "text/plain": [ "array([[ 70, 240],\n", " [190, 753]])" ] }, "metadata": { "tags": [] }, "execution_count": 158 } ] }, { "cell_type": "markdown", "metadata": { "id": "atnlUnp1e0ie" }, "source": [ "Можно наоборот" ] }, { "cell_type": "code", "metadata": { "id": "lRsvxql3e0ie", "colab": { "base_uri": "https://localhost:8080/" }, "outputId": "c3001fb3-e114-485d-f0d1-3688b64d9b90" }, "source": [ "np.einsum('jk,ij->ik', B, A) " ], "execution_count": 159, "outputs": [ { "output_type": "execute_result", "data": { "text/plain": [ "array([[ 70, 240],\n", " [190, 753]])" ] }, "metadata": { "tags": [] }, "execution_count": 159 } ] }, { "cell_type": "markdown", "metadata": { "id": "UZklEsQ6e0ie" }, "source": [ "Квадратная матрица" ] }, { "cell_type": "code", "metadata": { "id": "WH2V7drme0if", "colab": { "base_uri": "https://localhost:8080/" }, "outputId": "d5f29a0a-2fd6-46e4-ae98-b0ee3bfbf82f" }, "source": [ "C = np.arange(9).reshape((3, 3))\n", "C" ], "execution_count": 160, "outputs": [ { "output_type": "execute_result", "data": { "text/plain": [ "array([[0, 1, 2],\n", " [3, 4, 5],\n", " [6, 7, 8]])" ] }, "metadata": { "tags": [] }, "execution_count": 160 } ] }, { "cell_type": "markdown", "metadata": { "id": "GllXtuXde0if" }, "source": [ "Диагональ" ] }, { "cell_type": "code", "metadata": { "id": "bfR_xtA9e0if", "colab": { "base_uri": "https://localhost:8080/" }, "outputId": "8f207f5f-ec05-48cd-a15c-a6c96553226d" }, "source": [ "np.einsum('ii->i', C)" ], "execution_count": 161, "outputs": [ { "output_type": "execute_result", "data": { "text/plain": [ "array([0, 4, 8])" ] }, "metadata": { "tags": [] }, "execution_count": 161 } ] }, { "cell_type": "markdown", "metadata": { "id": "XJQE3Flhe0if" }, "source": [ "След" ] }, { "cell_type": "code", "metadata": { "id": "Yk_q9fJre0if", "colab": { "base_uri": "https://localhost:8080/" }, "outputId": "71d68e4a-3169-4f16-84bf-1fdb82836283" }, "source": [ "np.einsum('ii->', C)" ], "execution_count": 162, "outputs": [ { "output_type": "execute_result", "data": { "text/plain": [ "12" ] }, "metadata": { "tags": [] }, "execution_count": 162 } ] }, { "cell_type": "markdown", "metadata": { "id": "y5wkPHLte0if" }, "source": [ "Какая-то странная операция" ] }, { "cell_type": "code", "metadata": { "id": "sMgajVfue0if", "colab": { "base_uri": "https://localhost:8080/" }, "outputId": "d02658a5-9125-465c-dc37-a24c2ff1595c" }, "source": [ "np.einsum('ij,kj,jl->ilk', A, C, B) " ], "execution_count": 163, "outputs": [ { "output_type": "execute_result", "data": { "text/plain": [ "array([[[ 130, 340, 550],\n", " [ 380, 1100, 1820]],\n", "\n", " [[ 340, 910, 1480],\n", " [1100, 3359, 5618]]])" ] }, "metadata": { "tags": [] }, "execution_count": 163 } ] }, { "cell_type": "markdown", "metadata": { "id": "j_brnaqae0if" }, "source": [ "**Упражнение.** Создайте матрицы $A\\in\\mathbb{R}^{3\\times2}, B\\in\\mathbb{R}^{2\\times2}$. Посчитайте $\\text{tr} (ABBA^T)$" ] }, { "cell_type": "code", "metadata": { "id": "E9mdcyU0-KsL", "colab": { "base_uri": "https://localhost:8080/" }, "outputId": "ac9de8fe-45a6-41ca-a810-2e528ae514da" }, "source": [ "A = np.array([[0, 1], [2, 3], [4, 5]])\n", "B = np.array([[0, 1], [100, 30]])\n", "print(A)\n", "print(B)" ], "execution_count": 164, "outputs": [ { "output_type": "stream", "text": [ "[[0 1]\n", " [2 3]\n", " [4 5]]\n", "[[ 0 1]\n", " [100 30]]\n" ], "name": "stdout" } ] }, { "cell_type": "markdown", "metadata": { "id": "oJqxb1iZh0N9" }, "source": [ "Элемент квадратной матрицы $ABBA^T$ на позиции $(i, m)$ можно представить как\n", "$$\\sum_j\\sum_k\\sum_l a_{ij}b_{jk}b_{kl}a_{ml}.$$\n", " \n", "Результат — сумма диагональных элементой этой матрицы, то есть \n", "$$ \\text{tr} (ABBA^T) = \\sum_i\\sum_j\\sum_k\\sum_l a_{ij}b_{jk}b_{kl}a_{il}. $$\n", "\n", "Причем результат является числом. Код операции в виде сумм Эйншейна:" ] }, { "cell_type": "code", "metadata": { "id": "jTkZMGJMfkTb", "colab": { "base_uri": "https://localhost:8080/" }, "outputId": "16082abd-cbc4-4d78-de3c-8df56e22c780" }, "source": [ "np.einsum('ij,jk,kl,il->', A, B, B, A)" ], "execution_count": 165, "outputs": [ { "output_type": "execute_result", "data": { "text/plain": [ "115780" ] }, "metadata": { "tags": [] }, "execution_count": 165 } ] }, { "cell_type": "markdown", "metadata": { "id": "FFqg7hzchiKi" }, "source": [ "Проверим" ] }, { "cell_type": "code", "metadata": { "id": "hN49fr6Uhjyk", "colab": { "base_uri": "https://localhost:8080/" }, "outputId": "dd9c026c-54a3-41fd-c6c8-dd3ef8a7f8ec" }, "source": [ "np.sum(np.diag(A @ B @ B @ A.T))" ], "execution_count": 166, "outputs": [ { "output_type": "execute_result", "data": { "text/plain": [ "115780" ] }, "metadata": { "tags": [] }, "execution_count": 166 } ] } ] }