groupby + agg — главная тема. Также merge / join (left/right/outer/inner с дубликатами), pivot vs pivot_table vs melt, MultiIndex, transform vs apply (apply медленнее в 100×).
Эти трюки экономят 50-90% памяти и ускоряют операции в 10-100×. На senior-собесе обязательны.
Векторизация — главная фишка numpy. Python-loop работает 100-1000× медленнее. Broadcasting позволяет операции на массивах разной формы.
import numpy as np
# Python loop (медленный)
result = []
for x in range(1000000):
result.append(x * 2)
# NumPy vectorization (1000× быстрее)
arr = np.arange(1000000)
result = arr * 2
# Broadcasting: операция на массивах разной формы
a = np.array([1, 2, 3])
b = np.array([[10], [20], [30]])
c = a + b # shape (3,3), broadcasting автоматический
# np.where — условная замена
arr = np.where(arr > 500000, arr, 0)
scipy.stats — стандарт для A/B-тестов на Python. На собесе спросят: «какой тест применишь для пропорций?».
| Тест | Когда применять | Функция |
|---|---|---|
| t-test (Стьюдент) | Непрерывные, нормальное распределение | scipy.stats.ttest_ind |
| Welch t-test | Непрерывные, разные дисперсии | ttest_ind(equal_var=False) |
| Mann-Whitney U | Непараметрический (skew данные) | scipy.stats.mannwhitneyu |
| Chi-square | Категориальные / пропорции | scipy.stats.chi2_contingency |
| Kolmogorov-Smirnov | Сравнение распределений | scipy.stats.ks_2samp |
| Bootstrap CI | Когда нет параметрических предположений | scipy.stats.bootstrap |
Sklearn — стандарт для классического ML. Аналитику нужны: train_test_split, cross_val_score, базовые модели (LogReg, RandomForest), feature engineering, classification metrics.
Базовый принцип: «если ты пишешь for-loop по DataFrame — ты делаешь медленно». 5 главных альтернатив.
matplotlib — стандарт, низкоуровневый. seaborn — высокоуровневая обёртка над matplotlib для стат-графиков. plotly — интерактивные графики (zoom, hover). altair — декларативный (для дашбордов).
| Библиотека | Когда использовать |
|---|---|
| matplotlib | Базовый стандарт, кастомизация |
| seaborn | Статистические графики (boxplot, heatmap) |
| plotly | Интерактив, дашборды, презентации |
| altair | Декларативный синтаксис, сложные facet-графики |
| holoviews/bokeh | Большие данные, streaming |
На собесе спросят как ты организуешь работу в Jupyter. Хороший аналитик умеет писать notebook так, чтобы коллега мог его открыть и понять за 5 минут.
Обязательно: pandas (groupby/merge/pivot), numpy (basic vectorization), matplotlib/seaborn (визуализация). Достаточно знать: scipy.stats (t-test, chi-square), sklearn (train_test_split, простые модели), jupyter notebook.
Pandas — стандарт (95% компаний). Polars быстрее на 10-100× для больших данных (Apache Arrow + Rust), но экосистема меньше (sklearn-input не поддерживает). На собесе спросят pandas; polars знать как plus.
Замена Python-loop на массовую операцию через numpy/pandas. Например, df["a"] * 2 быстрее чем [x * 2 for x in df["a"]] в 100-1000×. На собесе спросят: оптимизируй apply через vectorization (groupby + transform или просто арифметика на колонках).
1) scipy.stats.ttest_ind для непрерывных метрик (с условием нормальности). 2) scipy.stats.mannwhitneyu для непараметрических. 3) Для пропорций — z-test (statsmodels.stats.proportion). 4) Bootstrap для надёжной оценки CI. 5) CUPED через scipy.stats.linregress для variance reduction.
С нуля до Junior: 100-150 задач pandas (groupby, merge, pivot). До Middle: +100 на numpy/scipy + 50 алгоритмов. До Senior: +50 design-задач + ML basics. У нас 530+ задач с автопроверкой в браузере — закроют всё с запасом.
apply возвращает любой результат (scalar, Series, DataFrame). transform возвращает Series той же длины что input — для broadcasting агрегата обратно. Пример: df["pct"] = df.groupby("user")["amount"].transform(lambda x: x / x.sum() * 100).
merge — join по ключу (как SQL JOIN). concat — стек по оси (вертикально/горизонтально). Если нужно объединить таблицы с общим ключом — merge. Если просто склеить или добавить ряды — concat.
Иерархический индекс — например, (страна, город) как составной ключ. Полезно для groupby с несколькими ключами + pivot_table. На собесе спросят: «как получить только Россия из MultiIndex?» — ответ через .loc[("Россия",)] или .xs("Россия", level=0).
Чаще всего из-за object dtype (строки). Решения: astype("category") для повторяющихся (страны, категории); dtype="int8/int16" для целых с малым диапазоном; chunksize в read_csv для streaming; parquet вместо csv (10× меньше).
np.array — без индекса, однородный тип. pd.Series — c индексом (label), может хранить mixed types через object dtype. Series под капотом — это np.array + labels. Для performance critical — np.array; для labelled data — Series.