Физтех.Статистика
Информация не актуальна. Сайт переехал на miptstats.github.io
Скачать ipynb
В данном ноутбуке мы быстро повторим основы библиотек Python для анализа данных. Если вы захотите более подробно разобраться в каком-то их разделов, смотрите Питон-ноутбуки и видеолекции на нашем сайте в разделе Python для анализа данных.
1. Anaconda¶
Anaconda — это дистрибутив Python, в который встроен пакетный менеджер conda
. Этот инструмент позволяет выделить отдельные окружения для ваших проектов, например, на Python или R. В каждом конкретном окружении будут свои версии языков программирования и библиотек. Это позволит не запутаться в том, какие версии библиотек у вас установлены, а таже даст вам возможность переносить окружения.
Установку можете произвести с официального сайта.
Пример создания окружения mipt-stats
:
conda create -n mipt-stats python=3.7 r=3.6 --yes
Активация и деактивация:
conda activate mipt-stats
conda deactivate
Чтобы поставить пакеты, используйте команду conda install
:
conda install numpy
Чтобы понять, как работать с Anaconda оптимальнее, смотрите полную версию материала.
1.1 Альтернативы¶
Если вы используете Linux-систему, то чаще проще обойтись без Anaconda, а использовать
pip
, например,pip install numpy
В таком случае тоже можно настроить виртуальное окружение. Однако не стоит смешивать использование
pip
иconda
!Если вы не хотите ничего себе устанавливать, например, из-за малых мощностей, можно использовать Google Colab. Но в таком случае каждый раз придется заново настраивать окружение, кроме того, среда выполнения может отключаться при длительном простое.
2. Jupyter¶
Jupyter предоставляет веб-интерфейс для редактирования jupyter-ноутбуков. Это удобный инструмент для того, чтобы быстро писать код на Python (или других языках), проверять гипотезы, строить графики, делать интерактивные визуализации и делиться результатами с коллегами.
Чтобы запустить интерфейс, поставьте в conda
пакет jupyter
и выполните в консоли команду
jupyter notebook
Jupyter-ноутбук состоит из ячеек с кодом, с markdown, а также с сырым текстом. Работать с ячейкой можно в двух режимах: Command Mode и Edit Mode. Чтобы переходить между ними, используйте Esc
и Enter
.
В Edit Mode управление похоже на vim
, справку по Command Mode можно посмотреть с помощью сочетания клавиш Esc + H
.
При написании кода, кроме функций языка программирования, можно пользоваться магией Юпитера, или jupyter magics. Это отдельный метаязык внутри jupyter, команды которого начинаются на %
. Можете открыть список всех доступных команд:
%lsmagic
Есть magics, которые применяются к строке или всей клетке в целом. Чтобы посмотреть помощь по интересующей команде, можно вызвать help:
?%lsmagic
Впоследствии увидим, как можно замерить производительность вашей программы при помощи %%time
.
Если хотите посмотреть подробный обзор jupyter magic, узнать о преимуществах Jupyter, узнать полезные сочетания клавиш и установить удобные плагины, обращайтесь к полным материалам по Jupyter.
3. NumPy¶
В пакете NumPy представлены удобные функции для работы c $n$-мерными массивами. В нём имеются функции для поэлементных операций, а также для работы с массивами, как с математическими объектами, например, функции для линейной алгебры.
Они реализованы на C++, поэтому гораздо эффективнее аналогичных реализаций на Python.
import numpy as np
3.1 Основы¶
Создавать массивы можно различными способами.
# Из списка
a = np.array([0, 2, 1])
# Из равномерной сетки
grid = np.linspace(0, 1, 500)
# Перечисление 0, 1, 2, 3, 4
nat_grid = np.arange(5)
# Заполненный нулями
zeros = np.zeros((1, 2, 3))
У массивов можно узнать их размерность, форму и число элементов
print(zeros.ndim, zeros.shape, zeros.size)
Индексация похожа на индексацию списков
print(a[2:1:-1])
print(grid[::100])
print(zeros[:, :2, :2])
3.2 Соединение массивов и их форма¶
Из одномерного массива можно сделать двумерный, указав необходимую форму.
A = np.arange(6).reshape((2, 3))
A
Два массива можно склеить горизонтально
B = np.zeros((2, 5))
np.hstack([A, B])
и вертикально
B = np.zeros((1, 3))
np.vstack([A, B])
3.3 Операции над массивами¶
Обычные арифметические операции работают поэлементно.
a = np.array([1, 2, 3])
b = np.array([3, 4, 5])
print(a * b)
print(np.sin(a))
Двумерный массив можно умножить на одномерный, как матрицу на вектор. Операция @
реализует матричное умножение
A = np.ones((2, 3))
b = np.ones(3)
A @ b
Транспонировать матрицу можно с помощью метода T
A.T.shape
3.4 Способы суммирования¶
Простое суммирование возвращает сумму всех элементов массива.
print(np.sum(a))
print(a.sum())
С многомерными массивами суммирование может работать сложнее. Например, можно суммировать вдоль определённой оси и получать не одно число, а массив.
a = np.ones((3, 4), dtype=int)
print(a.sum(axis=1))
print(a.sum(axis=0))
Для более продвинутых способов суммирования существуют, например, суммы Эйнштейна.
A = np.array([0, 1, 2])
B = np.array([[10, 15, 20], [100, 150, 200]])
print(A)
print(B)
np.einsum('i,ji->j', A, B)
В данном случае индексы суммирования приводят к такому вычислению:
- $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$.
- $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$.
Чтобы подробно разобраться в синтаксисе, посмотрите полный материал.
3.5 Бродкастинг¶
Broadcasting — процедура обработки массивов с различными формами во время арифметических операций. При соблюдении определенных ограничений меньший массив приводится к форме по большему массиву.
Рассмотрим поэлементное умножение двух массивов одинаковой формы
a = np.array([1.0, 2.0, 3.0])
b = np.array([2.0, 2.0, 2.0])
a * b
А теперь массивы разной формы
a = np.array([1.0, 2.0, 3.0])
b = 2.0
a * b
Результат получился тем же, поскольку в данном случае произошло растяжение массива b
до размеров массива a
с помощью дублирования элементов массива b
.
Примечание. Термин "растяжение" используется лишь для понимания. Операции реализуются более "умным" способом без лишнего копирования элементов.
Правило бродкастинга
При работе с двумя массивами numpy сравнивает их формы начиная с крайних правых размерностей. Два измерения совместимы, если
- они равны или
- одна из них равна 1.
Если эти условия не выполняются, возникает
ValueError
.
Посмотрим еще на пример
a = np.array([[ 0.0, 0.0, 0.0],
[10.0, 10.0, 10.0],
[20.0, 20.0, 20.0],
[30.0, 30.0, 30.0]])
b = np.array([1.0, 2.0, 3.0])
a + b
Растяжение в данном случае произошло следующим образом
А если размеры будут не совместимы, то произойдет ошибка
b = np.array([1.0, 2.0, 3.0, 4.0])
a + b
Если массивы имеют несовместимый размер, можно их сначала привести к одной форме
a = np.array([0.0, 10.0, 20.0, 30.0])
b = np.array([1.0, 2.0, 3.0])
a.reshape((-1, 1)) + b
Соответствующее растяжение
4. Matplotlib¶
Модуль matplotlib
— одно из популярных средств для построения графиков. При использовании matplotlib
не забудьте написать %matplotlib inline
для того, чтобы графики отображались в вашем окне браузера.
Начнём с построения простых графиков.
import numpy as np
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
%matplotlib inline
График, соединяющий точки, строится с помощью plt.plot
. Передаём список $x$ и $y$. Если не хотите соединять точки, используйте plt.scatter
.
plt.figure()
plt.plot([0, 0.25, 1], [0, 1, 0.5])
plt.scatter([0.25, 0.75, 1], [0, 0.5, 1])
plt.show()
Можно изображать несколько кривых, тогда они будут рисоваться разными цветами. Чтобы рисовать график функции, достаточно соединить много точек.
x = np.linspace(0, 2, 100)
plt.figure()
plt.plot(x, x)
plt.plot(x, x**2)
plt.plot(x, x**3)
plt.show()
На график можно добавить подписи, легенду, настроить цвета и стиль линий.
x = np.linspace(-2, 2, 100)
plt.figure(figsize=(8, 8))
plt.plot(x, x ** 2, linestyle='--', lw=3,
label='$y=x^2$', color='red')
plt.xlabel('Ось X'), plt.ylabel('Ось Y')
plt.legend(fontsize=15, loc=3)
plt.title('Парабола')
plt.grid(ls=':')
plt.show()
Закрасить область между двумя кривыми $y=y(x)$ можно с помощью функции plt.fill_between
, а между двумя кривыми вида $x = x(y)$ --- с помощью функции plt.fill_betweenx
.
Горизонтальные линии можно нарисовать с помощью plt.hlines
, а вертикальные --- с помощью plt.vlines
.
x = np.linspace(-10, 10, 100)
plt.figure(figsize=(12, 7))
plt.fill_between(x, -x+np.sin(x), x+np.sin(x), alpha=0.5)
plt.hlines([-10, -11, -12], -10, 10)
plt.xlabel('Ось X')
plt.ylabel('Ось Y')
plt.grid(ls=':')
plt.show()
Кроме графиков в двумерных координатах, matplotlib
позволяет строить трёхмерные графики или поверхности.
X = 10
N = 50
u = np.linspace(-X, X, N)
x, y = np.meshgrid(u, u)
r = np.sqrt(x ** 2 + y ** 2)
z = np.sin(r) / r
fig = plt.figure()
ax = Axes3D(fig)
ax.plot_surface(x, y, z, rstride=1, cstride=1, cmap='gnuplot')
plt.show()
Чтобы посмотреть, как ещё можно настраивать графики в matplotlib, строить контурные графики и делать пиксельные картинки, можете перейти к полному материалу.