Pandas шпаргалка для аналитика
Зачем аналитику pandas
Pandas — основная библиотека Python для работы с табличными данными. На собеседованиях аналитиков Python-блок почти всегда сводится к pandas: загрузить данные, отфильтровать, сгруппировать, объединить таблицы, посчитать метрику. Те же операции, что и в SQL, но в коде.
Эта шпаргалка — не учебник, а справочник. Каждый раздел: короткое объяснение и рабочий пример. Держите под рукой перед собеседованием.
На собеседованиях аналитиков pandas спрашивают реже, чем SQL, но в секции live-coding без него не обойтись. Особенно в продуктовых компаниях, где аналитик работает в Jupyter.
Загрузка данных
import pandas as pd
# CSV
df = pd.read_csv('orders.csv')
# Excel
df = pd.read_excel('report.xlsx', sheet_name='Sheet1')
# SQL-запрос
from sqlalchemy import create_engine
engine = create_engine('postgresql://user:pass@host/db')
df = pd.read_sql('SELECT * FROM orders WHERE created_at >= %s', engine, params=['2025-01-01'])
# Из словаря
df = pd.DataFrame({
'user_id': [1, 2, 3],
'revenue': [100, 250, 80]
})Базовый осмотр после загрузки:
df.shape # (строки, столбцы)
df.dtypes # типы данных
df.head(10) # первые 10 строк
df.describe() # статистика по числовым столбцам
df.info() # типы + пропуски
df.isnull().sum() # количество пропусков по столбцамФильтрация: loc, iloc, булевы маски
Булева фильтрация
Самый частый способ — условие в квадратных скобках.
# Заказы дороже 1000
big_orders = df[df['amount'] > 1000]
# Несколько условий: & (и), | (или), ~ (не)
active_big = df[(df['amount'] > 1000) & (df['status'] == 'completed')]
# Фильтр по списку значений
target_users = df[df['city'].isin(['Москва', 'Санкт-Петербург'])]
# Строковый фильтр
gmail = df[df['email'].str.contains('gmail', na=False)]Скобки вокруг каждого условия обязательны — без них Python неправильно разберёт приоритет операторов.
loc и iloc
loc — фильтрация по меткам (имена строк и столбцов). iloc — по числовым индексам.
# loc: строки по условию, конкретные столбцы
df.loc[df['amount'] > 1000, ['user_id', 'amount']]
# iloc: первые 5 строк, столбцы 0 и 2
df.iloc[:5, [0, 2]]На собеседовании спрашивают: «Чем отличается loc от iloc?» Ответ: loc работает с именами, iloc — с позициями. loc включает правую границу среза, iloc — нет.
groupby и агрегация
Аналог GROUP BY в SQL. Группируем строки и применяем агрегатную функцию.
# Средний чек по городам
df.groupby('city')['amount'].mean()
# Несколько агрегатов
df.groupby('city')['amount'].agg(['mean', 'median', 'count'])
# Разные агрегаты для разных столбцов
df.groupby('city').agg(
avg_amount=('amount', 'mean'),
total_orders=('order_id', 'count'),
unique_users=('user_id', 'nunique')
)Метод agg с именованными агрегатами — самый чистый способ. Результат сразу с понятными названиями столбцов.
Если нужно отфильтровать группы после агрегации (аналог HAVING в SQL):
city_stats = df.groupby('city')['amount'].sum()
city_stats[city_stats > 100000]merge: объединение таблиц
Аналог JOIN в SQL. Если вы знаете SQL-джойны, pandas merge — тот же набор операций.
# INNER JOIN — только совпадающие строки
result = orders.merge(users, on='user_id', how='inner')
# LEFT JOIN — все строки из левой таблицы
result = orders.merge(users, on='user_id', how='left')
# OUTER JOIN — все строки из обеих таблиц
result = orders.merge(users, on='user_id', how='outer')
# Ключи с разными именами
result = orders.merge(
users,
left_on='customer_id',
right_on='id',
how='left'
)pandas how |
SQL-аналог | Что остаётся |
|---|---|---|
inner |
INNER JOIN | Только совпадения |
left |
LEFT JOIN | Все из левой + совпадения |
right |
RIGHT JOIN | Все из правой + совпадения |
outer |
FULL OUTER JOIN | Все из обеих |
После merge проверяйте размер результата. Если строк стало больше, чем в левой таблице, — скорее всего, в правой таблице дубликаты по ключу. Это частая ловушка и на собеседованиях, и в реальной работе.
# Проверка: появились ли дубликаты после merge
print(f'До: {len(orders)}, После: {len(result)}')pivot_table и melt
pivot_table
Сводная таблица — аналог Excel pivot и SQL с CASE WHEN внутри агрегата.
# Средний чек по городу и месяцу
pivot = df.pivot_table(
values='amount',
index='city',
columns='month',
aggfunc='mean',
fill_value=0
)Строки — города, столбцы — месяцы, значения — средний чек. fill_value=0 заполняет пустые ячейки нулями.
Можно передать несколько агрегатов:
pivot = df.pivot_table(
values='amount',
index='city',
aggfunc=['mean', 'sum', 'count']
)melt
Обратная операция — из «широкого» формата в «длинный». Нужна, когда данные пришли в виде сводной таблицы, а вам нужны строки.
# Широкий формат: столбцы jan, feb, mar с выручкой
df_long = df.melt(
id_vars=['city'],
value_vars=['jan', 'feb', 'mar'],
var_name='month',
value_name='revenue'
)Результат: вместо трёх столбцов-месяцев — два столбца month и revenue, строк стало в три раза больше.
На собеседовании: просят привести данные к «нормальной форме» — это и есть melt. Обратная операция (из длинного в широкий) — pivot_table или pivot.
Работа с датами
На собеседованиях часто дают данные с датами и просят посчитать метрику по дням, неделям или месяцам. Pandas умеет это из коробки.
Преобразование в datetime
df['date'] = pd.to_datetime(df['date'])
# Формат указан явно
df['date'] = pd.to_datetime(df['date'], format='%d.%m.%Y')Если не преобразовать столбец в datetime, все операции с датами будут выдавать ошибки или неверные результаты. Это первое, что нужно сделать после загрузки.
Аксессор dt
Доступ к компонентам даты:
df['year'] = df['date'].dt.year
df['month'] = df['date'].dt.month
df['weekday'] = df['date'].dt.day_name()
df['week'] = df['date'].dt.isocalendar().weekresample
Агрегация временных рядов по периодам. Работает только с DatetimeIndex.
df = df.set_index('date')
# Дневная выручка → недельная
weekly = df['revenue'].resample('W').sum()
# Месячное среднее DAU
monthly_dau = df['dau'].resample('ME').mean()Периоды: 'D' — день, 'W' — неделя, 'ME' — месяц, 'QE' — квартал.
Альтернатива без DatetimeIndex — pd.Grouper:
df.groupby(pd.Grouper(key='date', freq='ME'))['revenue'].sum()Делает то же самое, но не требует менять индекс.
apply, map, transform
apply
Применяет функцию к каждой строке или столбцу.
# Категоризация чека
def size_category(amount):
if amount > 5000:
return 'large'
elif amount > 1000:
return 'medium'
return 'small'
df['size'] = df['amount'].apply(size_category)apply — мощный, но медленный инструмент. Для простых операций используйте векторные методы:
# Вместо apply — np.where (быстрее в десятки раз)
import numpy as np
df['is_big'] = np.where(df['amount'] > 5000, True, False)map
Замена значений по словарю:
status_map = {'new': 'Новый', 'completed': 'Завершён', 'cancelled': 'Отменён'}
df['status_ru'] = df['status'].map(status_map)transform
Как apply, но возвращает результат того же размера, что и исходный DataFrame. Удобен с groupby:
# Доля каждого заказа от суммы по пользователю
df['user_total'] = df.groupby('user_id')['amount'].transform('sum')
df['share'] = df['amount'] / df['user_total']Аналог оконной функции SUM() OVER (PARTITION BY user_id) в SQL.
Частые паттерны
Скользящее среднее (rolling)
df['revenue_7d'] = df['revenue'].rolling(window=7).mean()Аналог AVG() OVER (ROWS BETWEEN 6 PRECEDING AND CURRENT ROW) в SQL. Первые 6 строк будут NaN — окно ещё не заполнилось.
Нарастающий итог (cumsum)
df['cumulative_users'] = df['new_users'].cumsum()Аналог SUM() OVER (ORDER BY date) в SQL. Работает корректно, если данные отсортированы по дате — иначе результат будет бессмысленным.
Лаг (shift)
# Выручка за предыдущий день
df['prev_day'] = df['revenue'].shift(1)
# Изменение день к дню
df['daily_change'] = df['revenue'] - df['revenue'].shift(1)
# Процентное изменение
df['pct_change'] = df['revenue'].pct_change()shift(1) — аналог LAG(revenue, 1) в SQL. shift(-1) — аналог LEAD.
Ранжирование
# Ранг по выручке внутри каждого города
df['rank'] = df.groupby('city')['revenue'].rank(ascending=False, method='dense')Параметр method: 'min' = RANK(), 'dense' = DENSE_RANK(), 'first' = ROW_NUMBER(). Подробнее об оконных функциях SQL и их pandas-аналогах — в шпаргалке по оконным функциям.
Что спрашивают на собеседованиях
Типовые задачи на pandas, которые встречаются на интервью аналитиков:
Посчитайте retention D1 на pandas. Нужно найти дату первого визита каждого пользователя (groupby + min), затем merge с таблицей активности и проверить, был ли визит на следующий день.
Объедините две таблицы и найдите пользователей без заказов. Left merge + фильтрация по NaN в столбце из правой таблицы.
Посчитайте скользящее среднее выручки за 7 дней. rolling(7).mean() после сортировки по дате.
Найдите топ-3 товара по выручке в каждой категории. groupby + apply с nlargest, или rank + фильтрация.
Переведите данные из широкого формата в длинный. melt с указанием id_vars и value_vars.
Чем merge отличается от join? merge — по значениям столбцов (аналог SQL JOIN). join — по индексу. На практике merge используется чаще.
Больше задач по Python — в разделе подготовки. SQL-аналоги тех же операций — в разделе SQL.
Как тренироваться
Pandas нужно писать руками. Прочитать шпаргалку недостаточно — через неделю в голове останется только import pandas as pd. Навык формируется, когда вы решаете задачи: фильтруете, группируете, джойните, считаете метрики.
Тренажёр Карьерник содержит задачи по Python и pandas с разборами — от базовых операций до продвинутых паттернов с groupby и merge. Можно тренироваться по 15 минут в день в Telegram: этого достаточно, чтобы к собеседованию операции стали автоматическими.
Читайте также
- Оконные функции SQL: шпаргалка
- Как считать Retention
- Типы графиков для аналитика
- Подготовка к собеседованию аналитика
FAQ
Pandas или SQL — что учить первым?
SQL. Он проще, его спрашивают на каждом собеседовании, и большинство аналитических задач решаются именно в SQL. Pandas нужен как второй инструмент — для случаев, когда данные уже выгружены, нужна сложная трансформация или визуализация. На практике аналитик использует оба: SQL для запросов к базе, pandas для обработки результатов.
Что быстрее — pandas или SQL?
Для данных, которые помещаются в оперативную память (до нескольких ГБ), pandas и SQL сравнимы по скорости. Для больших объёмов SQL на сервере базы данных быстрее, потому что запрос выполняется на стороне СУБД с оптимизатором запросов, индексами и параллелизмом. Pandas загружает всё в память одного процесса. Если данные не помещаются в RAM, pandas упадёт — SQL продолжит работать.
Как запомнить синтаксис merge, если путаюсь в параметрах?
Запомните одну конструкцию: left.merge(right, on='key', how='left'). Это покрывает 80% случаев. Когда ключи называются по-разному — left_on и right_on. Когда нужно все строки из обеих таблиц — how='outer'. Остальное — вариации этого шаблона.