NumPy: шпаргалка для аналитика
Зачем аналитику NumPy
Pandas построен на NumPy. Любое «быстрое» решение в pandas — это под капотом NumPy-операция.
Для аналитика NumPy — фундамент. Его не спрашивают глубоко, но ожидают уверенного владения: массивы, векторизация, индексация, базовые агрегаты.
Создание массивов
import numpy as np
# Из списка
a = np.array([1, 2, 3])
b = np.array([[1, 2], [3, 4]]) # 2D
# Нули / единицы / range
np.zeros(5) # [0, 0, 0, 0, 0]
np.ones((2, 3)) # 2x3 единиц
np.arange(0, 10, 2) # [0, 2, 4, 6, 8]
np.linspace(0, 1, 5) # [0, 0.25, 0.5, 0.75, 1]
# Случайные
np.random.rand(3) # uniform [0, 1]
np.random.randn(3) # normal(0, 1)
np.random.randint(1, 10, 5) # целые [1, 10)
np.random.choice([1, 2, 3], 5) # выбрать из списка
# С seed для воспроизводимости
np.random.seed(42)Свойства массивов
a = np.array([[1, 2, 3], [4, 5, 6]])
a.shape # (2, 3)
a.ndim # 2 (размерность)
a.size # 6 (всего элементов)
a.dtype # int64Индексация
1D
a = np.array([10, 20, 30, 40, 50])
a[0] # 10
a[-1] # 50
a[1:3] # [20, 30]
a[::-1] # [50, 40, 30, 20, 10] — reverse2D
m = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]])
m[0, 1] # 2 (строка 0, столбец 1)
m[1, :] # [4, 5, 6] (строка 1)
m[:, 2] # [3, 6, 9] (столбец 2)
m[:2, 1:] # [[2, 3], [5, 6]] (подматрица)Boolean indexing
a = np.array([1, 2, 3, 4, 5])
a[a > 2] # [3, 4, 5]
a[(a > 1) & (a < 4)] # [2, 3]Fancy indexing
a = np.array([10, 20, 30, 40, 50])
a[[0, 2, 4]] # [10, 30, 50]Векторизация
Главное преимущество NumPy — никаких Python-циклов:
# Плохо (медленно)
result = []
for x in arr:
result.append(x ** 2 + 1)
# Хорошо (быстро)
result = arr ** 2 + 1На собесе: «Как ускорить Python-цикл?» Почти всегда ответ: заменить на векторную NumPy/pandas-операцию.
Broadcasting
Операции между массивами разных форм:
a = np.array([[1, 2, 3], [4, 5, 6]]) # 2x3
b = np.array([10, 20, 30]) # 1x3
a + b
# [[11, 22, 33], [14, 25, 36]] — b broadcasts к каждой строке
a + 100 # скаляр broadcasts ко всем элементамПравило: формы совместимы, если одна из размерностей равна 1 или совпадает с другой.
Попробовать силы на подобных вопросах проще всего в тренажёре Карьерник — прямо в Telegram, без регистрации через сайт.
Агрегаты
a = np.array([[1, 2, 3], [4, 5, 6]])
a.sum() # 21 (все)
a.sum(axis=0) # [5, 7, 9] (по столбцам)
a.sum(axis=1) # [6, 15] (по строкам)
a.mean(), a.std(), a.min(), a.max(), a.median() # median отдельно: np.median(a)
np.percentile(a, 50) # медиана
np.percentile(a, [25, 50, 75]) # квартилиМатематические функции
np.sqrt(a)
np.exp(a)
np.log(a)
np.log2(a)
np.sin(a), np.cos(a)
np.abs(a)
np.round(a, 2)
np.ceil(a), np.floor(a)Linear algebra
A = np.array([[1, 2], [3, 4]])
B = np.array([[5, 6], [7, 8]])
A @ B # матричное умножение (PE или np.dot)
A * B # поэлементное
A.T # транспонирование
np.linalg.inv(A) # обратная
np.linalg.det(A) # детерминант
np.linalg.eig(A) # собственные значенияИзменение формы
a = np.arange(12) # [0, 1, ..., 11]
a.reshape(3, 4) # 3x4 матрица
a.reshape(-1, 4) # -1 = авто (3), 4 столбца
a.flatten() # обратно в 1D
# Добавить измерение
a[:, np.newaxis] # (12,) → (12, 1)
a[np.newaxis, :] # (12,) → (1, 12)Конкатенация
np.concatenate([a1, a2]) # по axis=0
np.concatenate([a1, a2], axis=1) # по столбцам
np.vstack([a1, a2]) # вертикально
np.hstack([a1, a2]) # горизонтально
np.stack([a1, a2]) # новое измерениеСортировка
a = np.array([3, 1, 4, 1, 5])
np.sort(a) # [1, 1, 3, 4, 5]
np.argsort(a) # [1, 3, 0, 2, 4] (индексы после сортировки)
a[np.argsort(a)] # = np.sort(a)Пройти 30–50 задач по теме за вечер можно в Telegram-тренажёре. Это то, что отличает «знаю» от «уверенно отвечу на собесе».
Уникальные и статистика
np.unique(a) # уникальные
np.unique(a, return_counts=True) # + счётчики
np.bincount(a) # частоты (для integer)
np.histogram(a, bins=10) # гистограммаNaN-обработка
a = np.array([1, 2, np.nan, 4])
np.isnan(a) # [F, F, T, F]
np.nanmean(a) # 2.33 (игнорирует NaN)
np.nansum(a) # 7
np.nanmedian(a)
# Заменить NaN
np.nan_to_num(a, nan=0) # [1, 2, 0, 4]10 задач
1. Нормализовать массив
a_norm = (a - a.mean()) / a.std()2. Применить функцию к каждому элементу
# Не циклом! Векторизованно
result = np.where(a > 0, a ** 2, 0)3. Найти индексы всех элементов > 10
np.where(a > 10)[0]4. Посчитать в диапазонах (binning)
bins = [0, 10, 100, 1000]
np.digitize(a, bins)5. One-hot encoding
classes = np.unique(a)
one_hot = (a[:, np.newaxis] == classes).astype(int)6. Топ-K значений
top_k_indices = np.argpartition(a, -k)[-k:]
top_k = a[top_k_indices]7. Кумулятивная сумма
np.cumsum(a)8. Проверить, все ли положительные
np.all(a > 0)9. Скользящее среднее (np.convolve)
window = np.ones(7) / 7
ma = np.convolve(a, window, mode='valid')10. Декартово произведение
# Все пары из двух массивов
np.array(np.meshgrid(a, b)).T.reshape(-1, 2)Как тренироваться
NumPy учится через мини-задачи: создать, отфильтровать, агрегировать, заменить NaN. Каждая операция в pandas под капотом — NumPy, и понимание базы ускоряет мышление.
Тренажёр Карьерник содержит Python-блок с упражнениями на NumPy и pandas.
Совет: если вас просят ускорить Python-код на собесе — первым делом ищите циклы for и заменяйте на NumPy-векторизацию. Это 90% решений.
Читайте также
FAQ
NumPy или pandas?
Pandas для табличных данных с именованными столбцами. NumPy для низкоуровневых операций с массивами (матрицы, линейная алгебра, быстрая векторизация).
Как быстрее: NumPy или Python list?
NumPy в 10-100x быстрее на числовых операциях. Благодаря C-backend и векторизации.
Что такое broadcasting?
Правила NumPy для операций между массивами разных форм. Упрощает код и ускоряет — не нужно вручную делать reshape.
np.where или маска?
Маска (a[a > 0]) — если нужен фильтр. np.where — если нужна замена по условию: np.where(a > 0, a, -a).