Создание массивов
Массив хранит значения одного типа в сетке с любым числом измерений.
| Задача | Код |
|---|
| Импорт NumPy | import numpy as np |
| Из списка | np.array([1, 2, 3]) |
| 2D из вложенных списков | np.array([[1, 2, 3], [4, 5, 6]]) |
| Нули, единицы, одно значение | np.zeros((2, 3)), np.ones(4), np.full((2, 2), 7) |
| Диапазон с шагом (без конца) | np.arange(0, 10, 2) # [0 2 4 6 8] |
| n равноотстоящих точек (с концом) | np.linspace(0, 1, 5) # [0. 0.25 0.5 0.75 1.] |
| Единичная матрица | np.eye(3) |
| Той же формы, что другой массив | np.zeros_like(m), np.ones_like(m) |
| Задать тип элементов | np.array([1, 2, 3], dtype=np.float32) |
| Координатные сетки | xx, yy = np.meshgrid(np.arange(3), np.arange(2)) |
Свойства массива
| Задача | Код |
|---|
| Форма: размер каждого измерения | m.shape # (3, 4) |
| Число измерений | m.ndim # 2 |
| Число элементов | m.size # 12 |
| Тип элементов | m.dtype # int64 |
| Преобразовать тип | m.astype(np.float64) |
| Длина первого измерения | len(m) # 3 |
| Обратно в список Python | m.tolist() |
| Печатать меньше знаков после запятой | np.set_printoptions(precision=3, suppress=True) |
Индексы и срезы
Срезы это представления (view): они делят память с исходным массивом. Маски и списки индексов возвращают копии.
| Задача | Код |
|---|
| Первый и последний элемент | a[0], a[-1] |
| Срез start:stop (без stop) | a[1:4] # [20 30 40] |
| Каждый второй, в обратном порядке | a[::2], a[::-1] |
| Один элемент 2D-массива | m[1, 2] # 6 |
| Строка, столбец | m[0], m[:, 1] |
| Блок строк и столбцов | m[:2, 1:3] |
| Элементы по условию | a[a > 25] # [30 40 50] |
| Несколько условий | a[(a > 15) & (a < 45)] |
| Выбор по списку позиций | a[[0, 2, 4]] |
| Позиции, где условие выполнено | np.flatnonzero(a > 25) # [2 3 4] |
| Выбор для каждого элемента | np.where(a > 25, a, 0) |
| Копия перед изменением среза | part = a[1:3].copy() |
| Задать значения по маске | a[a > 40] = 0 |
Математика и broadcasting
Операторы работают поэлементно. Broadcasting растягивает скаляр, строку или столбец до формы другого массива.
| Задача | Код |
|---|
| Поэлементная арифметика | x + y, x - y, x * y, x / y, x ** 2 |
| Со скаляром | x * 10 |
| Корень, экспонента, логарифм | np.sqrt(x), np.exp(x), np.log(x) |
| Модуль, округление | np.abs(x - 5), np.round(x / 3, 2) |
| Ограничить значения диапазоном | np.clip(x, 2, 8) |
| Поэлементный максимум | np.maximum(x, 3) |
| Скалярное произведение | x @ y # 37.0 |
| Центрировать столбцы (broadcast строки) | m - m.mean(axis=0) |
| Масштабировать строки (broadcast столбца) | m / m.sum(axis=1, keepdims=True) |
| Безопасное сравнение float | np.isclose(0.1 + 0.2, 0.3) # True, np.allclose(x, y) |
| Тригонометрия и pi | np.sin(np.pi / 2) # 1.0 |
Агрегация по оси
axis=0 идёт вниз по строкам и даёт по одному результату на столбец. axis=1 идёт поперёк столбцов и даёт по одному результату на строку.
| Задача | Код |
|---|
| Сумма всех элементов | m.sum() # 21 |
| Результат по каждому столбцу | m.sum(axis=0) # [5 7 9] |
| Результат по каждой строке | m.sum(axis=1) # [ 6 15] |
| Среднее и стандартное отклонение | m.mean(), m.std(), m.mean(axis=0) |
| Минимум, максимум | m.min(), m.max(axis=1) |
| Позиция максимума | m.argmax(), m.argmax(axis=1) |
| Медиана и перцентили | np.median(m), np.percentile(m, [25, 50, 75]) |
| Нарастающая сумма | np.cumsum(m, axis=1) |
| Произведение всех элементов | m.prod() # 720 |
| Хотя бы один, все, сколько | (m > 4).any(), (m > 0).all(), np.count_nonzero(m > 2) |
Изменение формы и объединение
Reshape сохраняет элементы и меняет форму, поэтому общий размер должен остаться прежним.
| Задача | Код |
|---|
| Новая форма | a.reshape(2, 3) |
| Один размер NumPy вычислит сам | a.reshape(3, -1), a.reshape(-1, 1) |
| Вытянуть в 1D | m.ravel(), m.flatten() |
| Транспонировать | m.T |
| Добавить измерение | a[:, np.newaxis], np.expand_dims(a, axis=0) |
| Убрать измерения размера 1 | np.squeeze(np.ones((1, 3, 1))) |
| Склеить по существующей оси | np.concatenate([a, a]) |
| Сложить строки или столбцы | np.vstack([m, m]), np.hstack([m, m]) |
| 1D-массивы как столбцы | np.column_stack([a, a ** 2]) |
| Сложить по новой оси | np.stack([a, a], axis=0) # shape (2, 6) |
| Разбить на части | np.split(a, 3), np.array_split(a, 4) |
| Повторить или замостить | np.repeat([1, 2], 2) # [1 1 2 2], np.tile([1, 2], 2) # [1 2 1 2] |
Сортировка, поиск и уникальные значения
| Задача | Код |
|---|
| Отсортированная копия | np.sort(a) |
| По убыванию | np.sort(a)[::-1] |
| Индексы для сортировки | np.argsort(a) |
| Три наибольших значения | np.sort(a)[-3:] |
| Уникальные значения и их число | values, counts = np.unique(a, return_counts=True) |
Имена в NumPy 2 (unique_values может быть не отсортирован) | np.unique_values(a), np.unique_counts(a) |
| Есть ли элемент в списке? | np.isin(a, [1, 9]) |
| Позиция вставки в отсортированный массив | np.searchsorted([1, 3, 5, 7], 4) # 2 |
| Операции над множествами | np.intersect1d(a, [1, 2, 10]), np.union1d(a, [10]), np.setdiff1d(a, [1]) |
| Сортировка строк по столбцу | m[m[:, 1].argsort()] |
Случайные числа
Создай один Generator с seed и бери все числа из него, тогда результаты будут повторяться от запуска к запуску.
| Задача | Код |
|---|
| Генератор с seed | rng = np.random.default_rng(42) |
| Float в [0, 1) | rng.random(3) |
| Целые числа, без верхней границы | rng.integers(1, 7, size=10) |
| Нормальное распределение | rng.normal(loc=0, scale=1, size=(2, 3)) |
| Равномерные float в диапазоне | rng.uniform(5, 10, size=4) |
| Выбор из списка | rng.choice(["a", "b", "c"], size=5) |
| Выбор без повторов | rng.choice(10, size=3, replace=False) |
| Выбор с весами | rng.choice(["H", "T"], size=10, p=[0.7, 0.3]) |
| Перемешанная копия, перемешать на месте | rng.permutation(a), rng.shuffle(a) |
| Биномиальные и пуассоновские величины | rng.binomial(10, 0.5, size=5), rng.poisson(3, size=5) |
Линейная алгебра
| Задача | Код |
|---|
| Матричное произведение | A @ A |
| Решить Ax = b | np.linalg.solve(A, b) # [0.8 1.4] |
| Обратная матрица и определитель | np.linalg.inv(A), np.linalg.det(A) |
| Длина вектора | np.linalg.norm(b) |
| Собственные значения и векторы | values, vectors = np.linalg.eig(A) |
| Подогнать прямую | slope, intercept = np.polyfit(x, y, 1) |
| Внешнее произведение | np.outer([1, 2], [3, 4]) |
| Диагональ и след | np.diag(A), np.trace(A) |
Пропуски и особые значения
np.nan обозначает пропущенное значение float. Любая арифметика с ним даёт nan, поэтому используй функции с nan в названии или маску.
| Задача | Код |
|---|
| Пропущенное значение | np.nan |
| Найти пропуски | np.isnan(v), np.isnan(v).sum() |
| Убрать пропуски | v[~np.isnan(v)] |
| Заменить пропуски и бесконечности | np.nan_to_num(v, nan=0.0, posinf=0.0) |
| Проверки на бесконечность и конечность | np.inf, np.isfinite(v) |
| Статистики без учёта NaN | np.nanmean(v[:3]) # 2.0, np.nanmax(v) |
Сохранение и загрузка
| Задача | Код |
|---|
| Один массив, бинарный файл | np.save("data.npy", m), m = np.load("data.npy") |
| Несколько массивов в одном файле | np.savez("data.npz", x=x, y=y), np.load("data.npz")["x"] |
| Записать CSV | np.savetxt("data.csv", m, delimiter=",", fmt="%d") |
| Прочитать CSV | np.loadtxt("data.csv", delimiter=",") |
NumPy 2: старые имена и что писать теперь
В NumPy 2 удалили многие псевдонимы, поэтому код из старых туториалов может падать с AttributeError.
| Задача | NumPy 2 | Старая форма |
|---|
| Пропущенное значение | np.nan | np.NaN |
| Бесконечность | np.inf | np.Inf |
| 64-битный тип float | np.float64 | np.float_ |
| Площадь под кривой | np.trapezoid(y, x) | np.trapz(y, x) |
| Есть ли элемент в другом массиве? | np.isin(a, b) | np.in1d(a, b) |
| Сложить строки | np.vstack([a, a]) | np.row_stack([a, a]) |
| Произведение | np.prod(a) | np.product(a) |
| Случайные числа | rng = np.random.default_rng(0)
rng.random(3) | np.random.seed(0)
np.random.rand(3) |
Вызовы NumPy, на которых держится код для анализа данных, разбитые по задачам: создать массивы, изучить их, индексировать и делать срезы, считать поэлементно, агрегировать по оси, менять форму и объединять, сортировать и искать, генерировать случайные числа и решать задачи линейной алгебры. В каждой строке короткий фрагмент кода, который можно сразу вставить, и одна строчка о том, что он делает.
Всё здесь написано для NumPy 2, той версии, что работает на Coddy, а в последней таблице собраны имена, удалённые в NumPy 2, рядом с тем, что писать вместо них. В большинстве примеров используются a = np.array([3, 1, 4, 1, 5, 9, 2, 6]) и m = np.arange(12).reshape(3, 4). Только начинаешь с Python? Загляни в шпаргалку по Python и песочницу Python, а рядом с этой шпаргалкой держи шпаргалки по pandas, Matplotlib и scikit-learn.