pandasSQLинструментыаналитика

Pandas или SQL: когда что выбирать аналитику данных

2026-07-12 10 мин

Короткий ответ: не выбирать одно навсегда. SQL забирает тяжёлую работу рядом с данными — фильтрацию, джойны, агрегацию по миллионам строк на стороне базы. pandas подхватывает результат и доводит его до ума там, где SQL становится громоздким: сложный reshape, интерполяция пропусков, фичи для модели. В подавляющем большинстве моих рабочих задач это связка, а не развилка. Дальше разберу, как я решаю, что где делать, и покажу соответствие операций один в один — чтобы, зная один инструмент, вы быстро подхватили второй.

В чём вообще разница между SQL и pandas?

SQL — это язык запросов к базе данных. Ты описываешь, что хочешь получить, а движок (PostgreSQL, ClickHouse — что там у вас стоит) сам решает, как это посчитать, и делает это рядом с данными, на сервере. pandas — библиотека Python, которая держит таблицу (DataFrame) в оперативной памяти твоего процесса и позволяет делать с ней что угодно, по-программистски.

Отсюда растут все различия. SQL декларативный: пишешь GROUP BY, а как именно движок построит агрегацию — не твоя забота, у него есть оптимизатор. pandas императивный: ты сам собираешь цепочку преобразований и сам отвечаешь за то, влезет ли всё в память. SQL живёт там, где данные уже лежат. pandas живёт там, где ты пишешь код анализа — в ноутбуке, в скрипте, в пайплайне модели.

Простой критерий, которым я пользуюсь каждый день: если данные в базе и их много — начинаю с SQL. Если данные уже у меня в памяти и нужно что-то нетривиальное — беру pandas. Обычно за одну задачу я успеваю задействовать оба.

Когда задачу удобнее решать в SQL?

Я остаюсь в SQL, когда совпадает хотя бы одно из четырёх условий.

Данные лежат в базе, и их много. Тащить таблицу events на 200 млн строк в pandas, чтобы посчитать активных пользователей, — плохая идея: ты выкачаешь гигабайты по сети и положишь себе память. COUNT(DISTINCT user_id) посчитается на сервере за секунды и вернёт одно число.

Нужна агрегация на стороне сервера. GROUP BY, оконные функции, джойны нескольких больших таблиц — база для этого и создана, у неё есть индексы и оптимизатор запросов.

Нужна воспроизводимость. Запрос ложится в дашборд, в витрину, в регулярный отчёт. Его прочитает коллега через полгода. SQL как раз для этого — это общий язык команды: его читают аналитики, дата-инженеры и половина продактов.

SELECT
    date_trunc('day', created_at) AS day,
    count(DISTINCT user_id)       AS dau,
    count(*)                      AS events
FROM events
WHERE created_at >= now() - interval '30 days'
GROUP BY 1
ORDER BY 1;

Такой запрос вернёт 30 строк вместо миллионов. Дальше с ними уже можно работать хоть в pandas, хоть в таблице. Если хочется потренировать именно этот класс задач, у меня собран SQL-тренажёр с настоящим PostgreSQL в браузере, а частые конструкции лежат в справочнике по SQL под рукой.

Когда без pandas не обойтись?

pandas выигрывает там, где SQL начинает выглядеть как конструкция из палок и скотча.

Сложный reshape. Развернуть длинную таблицу в широкую и обратно, посчитать матрицу, сделать сводную с несколькими уровнями — в pandas это pivot_table, melt, stack/unstack в одну строку. На чистом SQL то же самое превращается в простыню из CASE-ов, которую потом страшно трогать.

Интерполяция и заполнение пропусков. Линейно достроить пропущенные значения по времени, протянуть последнее известное вперёд (ffill), сгладить скользящим окном — в pandas это встроено. В SQL приходится городить оконные функции с хитрыми условиями, и всё равно интерполяции из коробки нет.

ML-препроцессинг. Как только результат идёт в модель, начинается pandas: кодирование категорий, нормализация, генерация фич, стыковка с scikit-learn. Это его родная среда, и переносить её в SQL никто не станет.

Данные из разных источников. Выгрузка из базы, CSV от коллеги, ответ внешнего API — всё это сходится в один DataFrame, а не в одну базу.

import pandas as pd

# df пришёл из SQL: колонки day, dau, events
df = df.set_index('day').sort_index()

# выравниваем по дням, заполняем дыры, сглаживаем
df = df.asfreq('D')                         # ровная сетка по датам
df['dau'] = df['dau'].interpolate()         # линейная интерполяция пропусков
df['dau_7d'] = df['dau'].rolling(7).mean()  # скользящее среднее за неделю

Три строки — и у тебя ровный ряд без дыр и со сглаживанием. На SQL это заметно многословнее. Поработать с DataFrame можно в Python-тренажёре, а частые приёмы я вынес в справочник по pandas.

Почему я почти всегда использую обе, а не одну?

Потому что у них не пересекающиеся сильные стороны. Правильный вопрос звучит не «SQL или pandas», а «где провести границу между ними».

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

-- шаг 1: тяжёлая агрегация на сервере
SELECT
    u.country,
    date_trunc('week', o.created_at) AS week,
    sum(o.amount)                    AS revenue,
    count(*)                         AS orders
FROM orders o
JOIN users u ON u.id = o.user_id
WHERE o.status = 'paid'
  AND o.created_at >= now() - interval '180 days'
GROUP BY 1, 2;
# шаг 2: тонкая доводка в pandas
pivot = (df
    .pivot_table(index='week', columns='country',
                 values='revenue', aggfunc='sum')
    .fillna(0))

pivot_growth = pivot.pct_change().round(3)  # недельный рост по странам

Из базы приехало пару сотен строк, а разворот по странам и расчёт прироста я сделал в pandas за две строки. Посчитать pct_change по неделям прямо в SQL можно, но читать это потом будет больно. Именно такое разделение труда чаще всего и проверяют на собеседованиях — задачу дают сырую, а хотят увидеть, где вы поставите границу.

Какая операция SQL превращается в какую в pandas?

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

Один и тот же вопрос «выручка по странам, где заказов больше сотни» на двух языках:

SELECT country, sum(amount) AS revenue
FROM orders
GROUP BY country
HAVING count(*) > 100
ORDER BY revenue DESC;
res = (df.groupby('country')
         .agg(revenue=('amount', 'sum'),
              cnt=('amount', 'size'))
         .query('cnt > 100')
         .sort_values('revenue', ascending=False))

Видно один в один: GROUP BY стал groupby, HAVING — это query уже после агрегации, ORDER BYsort_values. Как только замечаешь эту симметрию, второй язык учится быстро: ты просто переводишь знакомые конструкции, а не зубришь новую логику с нуля.

Что быстрее на больших данных — SQL или pandas?

На больших данных, которые лежат в базе, — почти всегда SQL, и с большим отрывом. У базы есть индексы, оптимизатор и умение считать, не загружая всё в память сразу. pandas же тянет весь DataFrame в оперативку: как только таблица подбирается к объёму твоей RAM, начинается своп, и всё встаёт колом.

Практическое следствие простое: не выгружай в pandas то, что можешь свернуть в SQL. Нужен итог по 100 млн строк — пусть база вернёт агрегат, а не сырьё. Правило «фильтруй и агрегируй как можно раньше, у источника» экономит и память, и время, и нервы, и заодно делает код понятнее.

При этом pandas вовсе не медленный — он прекрасен на данных, которые влезают в память (условно до нескольких миллионов строк на обычной машине). Просто роль у него другая: не перемолоть терабайт, а гибко поработать с уже отобранным куском. Когда данные реально не влезают, аналитики уходят в ClickHouse, Spark или Polars — но это следующий разговор, и начинается он всё равно с крепкого SQL.

Что учить первым — SQL или pandas?

Если вы только заходите в аналитику данных — сначала SQL. Причин три. Его спрашивают на каждом собеседовании на позицию аналитика, без исключений. Без него вы физически не достанете данные — они лежат в базах. И порог входа ниже: базовый SELECT ... WHERE ... GROUP BY осваивается быстрее, чем питоновский синтаксис с индексами и осями DataFrame.

pandas беру вторым — когда SQL уже не пугает. К этому моменту groupby и merge ложатся легко, потому что вы уже понимаете GROUP BY и JOIN, остаётся выучить обёртку. Дальше учите их параллельно на реальных задачах, и связка складывается сама собой.

На доход это влияет прямо: вакансии, где просят и SQL, и Python, стабильно оплачиваются выше, чем «только SQL». Что и сколько платят за какой набор навыков, я разбираю в обзоре зарплат аналитика данных. А идти хочется системно и по шагам — есть курс по SQL с нуля, после которого pandas заходит почти без сопротивления.

С чего начать прямо сейчас?

Возьмите одну свою реальную задачу и честно разделите её на два шага: что можно свернуть запросом у источника и что придётся доводить в коде. Это упражнение ставит границу между инструментами в голове быстрее любой теории.

Дальше — практика и разбор того, как те же самые вопросы звучат на собеседованиях: именно там проверяют не знание синтаксиса, а умение выбрать инструмент под задачу. А если не хочется собирать программу по кускам, Pro-доступ открывает все задачи, кейсы и метрики разом, с проверкой решений и разбором ошибок. Инструмент — всегда лишь средство. Ценят не того, кто знает pandas или SQL, а того, кто быстро достаёт из данных ответ на вопрос бизнеса.

Связанная тема — SQL или Python: что учить первым аналитику данных.

Закрепи на практике
Python-задачи через pandas/numpy/scipy — попробуй бесплатно.
Python-тренажёр →