python собеседование аналитикpandas вопросы собеседованиеpandasсобеседование аналитика данныхnumpyподготовка к собеседованию

Python на собеседовании аналитика: pandas-вопросы

2026-06-30 13 мин

На собеседовании аналитика данных Python проверяют не как у разработчика — а как инструмент обработки данных. Ядро — pandas: от вас ждут, что вы умеете группировать (groupby), соединять таблицы (merge), чистить пропуски и дубликаты, считать оконные метрики (rolling, shift) и делать это векторизованно, а не через циклы for. Типовые задачи — парсинг логов, RFM-сегментация, сессионизация событий и скользящие средние. Отвечать нужно кодом и объяснением сложности, а не заученной теорией.

Python-секция на собесе аналитика редко бывает алгоритмической олимпиадой. Работодателю важно, сможете ли вы завтра взять сырой CSV или выгрузку из БД и превратить её в отчёт. Поэтому вопросы крутятся вокруг pandas и numpy, а «чистый» Python (генераторы, мутабельные дефолты, list comprehension) спрашивают точечно — чтобы отличить того, кто понимает язык, от того, кто копирует сниппеты. Ниже — карта того, что реально дают, с формулировками как на живых интервью в российских компаниях.

Почему pandas — главный навык аналитика, а не Python вообще?

Аналитик проводит большую часть времени в трансформации табличных данных: агрегации, джойны, фильтры, витрины. Ровно для этого создан pandas — библиотека с двумя структурами: Series (одна колонка с индексом) и DataFrame (таблица). Всё остальное в Python вы используете как обвязку вокруг неё.

Почему не только SQL? SQL заканчивается там, где начинается итеративная работа: быстрый EDA, нестандартная логика очистки, интеграция с моделями, графики. pandas даёт то, чего в SQL нет из коробки — например, df.describe() одной строкой или сложную оконную логику без переписывания запроса. Но важно понимать симметрию: почти всё, что вы делаете в pandas, имеет прямой аналог в SQL, и хороший интервьюер этого касается.

ОперацияSQLpandas
Фильтр строкWHERE amount > 100df[df.amount > 100]
Агрегация по группеGROUP BY user_iddf.groupby('user_id')
Соединение таблицJOIN ... ONdf.merge(other, on=...)
Оконная функцияSUM() OVER (PARTITION BY ...)df.groupby(...).transform('sum')
ДедупликацияSELECT DISTINCTdf.drop_duplicates()

Если вы понимаете эту таблицу «в обе стороны», половина вопросов закрыта. Отработать связку можно в тренажёре Python, где задачи идут от простого фильтра к оконным метрикам, а проверка кода — сразу в браузере.

Какие вопросы по groupby задают чаще всего?

groupby — самый частый вопрос, потому что через него проверяют понимание модели «split-apply-combine»: данные разбиваются на группы, к каждой применяется функция, результаты собираются обратно. Типичная формулировка: «Посчитай средний чек и число заказов по каждому пользователю».
df.groupby('user_id').agg(
    avg_check=('amount', 'mean'),
    orders=('order_id', 'count'),
).reset_index()

Что здесь проверяют и о чём стоит сказать вслух:

df['share'] = df['amount'] / df.groupby('user_id')['amount'].transform('sum')

Углубиться в нюансы groupby (несколько ключей, apply против встроенных агрегатов, as_index=False) можно в разборе pandas groupby.

Чем merge отличается от join и где ловушки с дубликатами?

merge в pandas — это SQL-JOIN: соединение двух таблиц по ключу. Главный вопрос интервьюера — понимаете ли вы типы соединения и что происходит с числом строк.
df.merge(orders, on='user_id', how='left')

Ключевые тезисы для ответа:

df.merge(orders, on='user_id', how='left', validate='one_to_many')
one_to_many требует, чтобы user_id был уникален в левой таблице (один пользователь — много заказов). Если это не так, pandas бросит ошибку — и это спасёт от молчаливого раздувания данных. Умение назвать validate сильно выделяет кандидата.

Почему векторизация быстрее apply и цикла for?

Это вопрос-водораздел между джуном и мидлом. Правильный ответ: pandas и numpy хранят данные в непрерывных C-массивах, и векторизованная операция выполняется единым проходом на уровне C, без интерпретатора Python на каждой строке. Цикл for и apply по строкам гоняют Python-интерпретатор на каждой итерации — отсюда разница в скорости на порядки.

Иерархия скорости, от быстрого к медленному:

Классическая задача: «Проставь категорию заказа: до 1000 — small, до 5000 — medium, иначе large». Плохой ответ — apply с функцией. Хороший — векторизация:

import numpy as np

df['bucket'] = np.select(
    [df.amount < 1000, df.amount < 5000],
    ['small', 'medium'],
    default='large',
)
np.select и np.where — то, что интервьюер хочет услышать вместо apply(lambda row: ...). Проговорите вслух: «Здесь я избегаю построчного apply, чтобы операция шла векторизованно». Это ровно тот сигнал, который отделяет вас от кандидата, пишущего медленный код.

Как правильно обрабатывать пропуски и дубликаты?

Очистка данных — то, чем аналитик занимается каждый день, поэтому вопросы про NaN и дубли почти гарантированы.

Пропуски. Сначала диагностика, потом стратегия:

df.isna().sum()              # сколько пропусков в каждой колонке
df.isna().mean().round(3)    # доля пропусков

Стратегии и когда их называть:

Главная ловушка, которую любят на собесе: NaN != NaN. Сравнение через == не найдёт пропуски — только isna(). И помните, что операции над NaN (например NaN + 5) дают NaN.

Дубликаты. Различайте полные и по подмножеству колонок:

df.duplicated().sum()                          # полные дубли строк
df.drop_duplicates(subset=['user_id', 'date'], keep='last')

Параметр keep (first/last/False) — частый уточняющий вопрос: keep='last' оставит последнюю запись, keep=False выкинет все повторы вообще. Скажите, что перед дедупликацией всегда стоит проверить, какие строки считаются дублями по бизнес-логике, а не механически.

Какие вопросы по оконным функциям в pandas задают?

Оконные операции — то, где аналитик обгоняет junior-разработчика. Основа — shift, rolling, expanding и cumsum, часто в связке с groupby.

df['dod_growth'] = df['revenue'] / df['revenue'].shift(1) - 1

df['ma7'] = df['revenue'].rolling(window=7, min_periods=1).mean()

Параметр min_periods — частый вопрос: без него первые 6 значений будут NaN.

df['user_cummean'] = df.groupby('user_id')['amount'].expanding().mean().reset_index(level=0, drop=True)

Развёрнутый разбор десяти оконных функций (rolling, shift, resample, rank, pct_change, diff и других) с примерами кода — в отдельной статье про окна и временные ряды в pandas.

Какие вопросы по «чистому» Python спрашивают у аналитика?

Помимо pandas, интервьюер задаёт 2-3 вопроса на понимание самого языка. Не глубокий CS, а типичные грабли.

Мутабельные аргументы по умолчанию. Классика, которую спрашивают почти всегда:

def add_item(item, box=[]):   # ОПАСНО
    box.append(item)
    return box

Список [] создаётся один раз при определении функции, а не при каждом вызове, — поэтому состояние «протекает» между вызовами. Правильно:

def add_item(item, box=None):
    if box is None:
        box = []
    box.append(item)
    return box

Проговорите причину: значения по умолчанию вычисляются один раз в момент объявления функции. Это точно тот ответ, что от вас хотят.

Генераторы vs списки. «Чем [x for x in data] отличается от (x for x in data)?» Список создаётся целиком в памяти сразу, генератор отдаёт элементы по одному лениво. Для большого файла логов генератор экономит память — читаете построчно, не грузя весь файл. Ключевые слова для ответа: yield, ленивость, O(1) по памяти против O(n).

Прочее, что всплывает точечно:

Эти вопросы разбирают в блоке подготовки к собеседованиям вместе с типовыми SQL и продуктовыми задачами.

Как решать типовые практические задачи: логи, RFM, сессии?

Практическая часть — это 1-2 задачи «дано вот такой датафрейм, посчитай вот это». Разберём четыре самых частых сценария.

1. Парсинг логов. Дан текстовый лог веб-сервера, нужно вытащить структуру. Ключ — векторизованные строковые методы через аксессор .str и регулярки:

pattern = r'(?P<ip>\d+\.\d+\.\d+\.\d+).*?"(?P<method>GET|POST) (?P<url>\S+)'
parsed = df['raw'].str.extract(pattern)
str.extract с именованными группами сразу даёт готовый DataFrame — это сильнее, чем apply с re.match по строкам.

2. RFM-сегментация. Классика e-commerce: Recency (как давно покупал), Frequency (как часто), Monetary (на сколько). Считается через groupby + qcut для разбивки на квантили:

snapshot = df['date'].max()
rfm = df.groupby('user_id').agg(
    recency=('date', lambda x: (snapshot - x.max()).days),
    frequency=('order_id', 'nunique'),
    monetary=('amount', 'sum'),
)
rfm['R'] = pd.qcut(rfm['recency'], 4, labels=[4, 3, 2, 1])

Тонкость, о которой стоит сказать: для Recency меньшее значение — лучше (недавняя покупка), поэтому метки квантилей разворачивают.

3. Сессионизация. Разбить поток событий пользователя на сессии: новая сессия начинается, если между событиями прошло больше 30 минут. Шаблон — сортировка, diff внутри группы, cumsum булева флага:

df = df.sort_values(['user_id', 'ts'])
gap = df.groupby('user_id')['ts'].diff() > pd.Timedelta('30min')
df['session_id'] = gap.groupby(df['user_id']).cumsum()

Идея cumsum по булевой маске (каждый разрыв увеличивает счётчик сессии) — то, что интервьюер хочет увидеть. Это же паттерн «gaps and islands» из SQL.

4. Скользящее среднее без утечки будущего. «Посчитай 7-дневное среднее по каждому магазину». Здесь важно не забыть сортировку по времени и группировку:

df = df.sort_values('date')
df['ma7'] = df.groupby('store_id')['sales'].transform(
    lambda s: s.rolling(7, min_periods=1).mean()
)

Все четыре задачи можно прогнать вживую в тренажёре Python: условие, редактор, автопроверка результата и разбор сложности — как на реальном собесе.

Как готовиться к Python-секции, чтобы не завалить?

Стратегия подготовки, которая работает лучше зубрёжки синтаксиса:

Чек-лист тем, которые нужно закрыть перед интервью: groupby/agg/transform, все типы merge и ловушка дубликатов, векторизация против apply, обработка NaN и дублей, оконные shift/rolling/cumsum, мутабельные дефолты и генераторы, и четыре практических паттерна выше (логи, RFM, сессии, скользящее среднее).

Где потренироваться?

Теория без практики на собесе не спасает — код нужно писать до автоматизма. Вот с чего начать:

Начните с одной задачи на groupby сегодня — и через две недели практики Python-секция перестанет быть узким местом на собеседовании.

Потренируй Python на практике
Тренажёр с автопроверкой и разбором. Первые задачи — без регистрации.
Открыть Python-тренажёр →