0Pricing
Pandas & NumPy Academy · Урок

Pandas или SQL: выбор подходящего инструмента

Сравните groupby/merge в Pandas с GROUP BY/JOIN в SQL и решите, на каком уровне следует выполнять каждое преобразование

«Pandas или SQL: выбор подходящего инструмента» — бесплатный урок Pandas & NumPy Academy на CoddyKit. Это урок 4 из 4. Ты можешь прочитать весь урок бесплатно ниже — а потом практиковать его прямо в браузере с встроенным редактором кода и ИИ-репетитором 24/7. Это часть пути обучения Pandas & NumPy Academy, и твой прогресс синхронизируется между веб-версией и приложением CoddyKit. Курс Pandas & NumPy Academy содержит 4 уроков всего.

Два инструмента с взаимодополняющими преимуществами

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

Преимущества SQL: с чем SQL справляется лучше

SQL обычно предпочтительнее, когда: данных много (от гигабайт до терабайт) и их нужно отфильтровать до загрузки; соединяются несколько больших таблиц, а индексы базы данных дают многократный прирост скорости; агрегации просты (SUM, COUNT, GROUP BY); набор результатов мал по сравнению с входными данными; или требуются параллельные чтения и записи (база данных сама обрабатывает транзакции и блокировки). Декларативный синтаксис SQL также позволяет оптимизаторам запросов автоматически выбирать лучший физический план.

-- SQL excels at:
-- 1. Filtering billions of rows using an index
SELECT * FROM orders WHERE customer_id = 12345;

-- 2. Joining large tables efficiently
SELECT o.order_id, c.name, SUM(o.amount)
FROM orders o
JOIN customers c ON o.customer_id = c.id
GROUP BY o.order_id, c.name;

-- 3. Window functions on ordered data
SELECT order_id, amount,
       SUM(amount) OVER (PARTITION BY customer_id ORDER BY order_date)
FROM orders;

Преимущества Pandas: с чем Pandas справляется лучше

Pandas обычно предпочтительнее, когда: требуется пользовательская логика на Python, которую невозможно выразить в SQL (предварительная обработка для машинного обучения, разбор строк, сложные алгоритмы); цепочка преобразований данных состоит из множества шагов; после анализа требуется немедленная визуализация; данные уже находятся в памяти, а дополнительные обращения к SQL добавят задержку; или Вы выполняете исследовательский анализ с интерактивными итерациями. Pandas также поддерживает нетабличные операции, например вычисления с матрицами и сглаживание временных рядов.

import pandas as pd

# Pandas excels at:
# 1. Custom Python logic that SQL cannot express
df['clean_name'] = df['name'].str.strip().str.title().str.replace(r'[^a-zA-Z ]', '', regex=True)

# 2. Vectorised string parsing
df[['first', 'last']] = df['full_name'].str.split(' ', n=1, expand=True)

# 3. Rolling statistics and time series
df['7day_avg'] = df['daily_sales'].rolling(7).mean()

# 4. Direct visualisation
# df.groupby('category')['sales'].sum().plot(kind='bar')

Сопоставление операций SQL и Pandas

Большинство операций SQL имеют прямые аналоги в Pandas. Знание обоих синтаксисов делает Вас более универсальным специалистом и помогает переводить решения с одного инструмента на другой. WHERE заменяется булевой индексацией или .query(); GROUP BY + SUM — вызовом .groupby().sum(); JOIN — вызовом pd.merge(); ORDER BY — вызовом .sort_values(); а DISTINCT — вызовом .drop_duplicates(). Смысл операций одинаков, различается только синтаксис.

import pandas as pd

df = pd.DataFrame({'region': ['N','S','N','E'], 'amount': [100,200,150,300]})

# SQL: SELECT region, SUM(amount) FROM df WHERE amount>100 GROUP BY region ORDER BY region
# Pandas:
result = (
    df[df['amount'] > 100]
    .groupby('region')['amount']
    .sum()
    .reset_index()
    .sort_values('region')
)
print(result)

Когда выбор определяется размером данных

Практическая схема выбора с учётом размера данных: меньше 100 MB — полностью используйте Pandas, накладные расходы SQL не оправданы; от 100 MB до 10 GB — фильтруйте и агрегируйте данные в SQL, а в Pandas загружайте итоговый DataFrame; от 10 GB до 1 TB — используйте SQL или Dask для обработки, а Pandas — только для итоговой сводки; больше 1 TB — используйте распределённый SQL (BigQuery, Spark SQL, Redshift). Никогда не пытайтесь загрузить таблицу размером 100 GB в Pandas на ноутбуке с 16 GB памяти — программа завершится с ошибкой или система начнёт активно использовать диск.

import pandas as pd
import sqlalchemy as sa

engine = sa.create_engine('sqlite:///large.db')

# Right approach: SQL handles the heavy lifting
summary_df = pd.read_sql_query(
    '''
    SELECT region, product_category,
           SUM(revenue) AS total_revenue,
           COUNT(DISTINCT customer_id) AS unique_customers
    FROM orders
    WHERE order_date >= '2024-01-01'
    GROUP BY region, product_category
    ''',
    con=engine
)
# summary_df is small — now do Pandas things on it
print(summary_df.sort_values('total_revenue', ascending=False))

Оконные функции SQL и rolling в Pandas

Оконные функции SQL (OVER (PARTITION BY ... ORDER BY ...)) мощны, но имеют ограничения: они хорошо вычисляют текущие ранги, предыдущие и следующие значения, а также простые скользящие агрегаты, однако сложные скользящие статистики (например, скользящую корреляцию Пирсона) выразить в SQL нельзя. rolling() и expanding() в Pandas охватывают гораздо более широкий спектр оконных вычислений, включая пользовательские функции через .apply(). Для стандартных оконных функций на больших объёмах данных предпочитайте SQL, а для сложной оконной логики — Pandas.

import pandas as pd

df = pd.DataFrame({
    'date': pd.date_range('2024-01-01', periods=30),
    'sales': [100 + i*10 + (i%7)*20 for i in range(30)]
})

# Pandas rolling — easy with arbitrary window functions
df['7d_mean'] = df['sales'].rolling(7).mean()
df['7d_std']  = df['sales'].rolling(7).std()
df['7d_corr'] = df['sales'].rolling(7).corr(df['sales'].shift(1))
print(df.tail())

Сложные соединения: гибкость Pandas

Соединения SQL основаны на равенстве ключей (с некоторыми исключениями). pd.merge_asof() в Pandas поддерживает нестрогие соединения по времени (сопоставление с ближайшим ключом, а не точное равенство), что особенно полезно для выравнивания временных рядов (например, для соединения цен акций с событиями сделок по ближайшей предшествующей цене). Pandas также поддерживает условные соединения с помощью merge и последующей фильтрации; в SQL для этого требуется подзапрос или соединение LATERAL. В таких продвинутых схемах соединения Pandas явно превосходит SQL.

import pandas as pd

trades = pd.DataFrame({
    'time': pd.to_datetime(['2024-01-01 10:00', '2024-01-01 10:05', '2024-01-01 10:12']),
    'symbol': ['AAPL', 'AAPL', 'AAPL'],
    'shares': [100, 200, 50]
})
prices = pd.DataFrame({
    'time': pd.to_datetime(['2024-01-01 10:00', '2024-01-01 10:10']),
    'price': [185.0, 186.5]
})

# Fuzzy join: match each trade to the nearest preceding price
result = pd.merge_asof(trades.sort_values('time'),
                       prices.sort_values('time'),
                       on='time', direction='backward')
print(result)

Pandas для профилирования данных, SQL для рабочих систем

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

import pandas as pd
import sqlalchemy as sa

engine = sa.create_engine('sqlite:///data.db')

# Development: sample in Pandas for fast iteration
df_sample = pd.read_sql_query(
    'SELECT * FROM orders ORDER BY RANDOM() LIMIT 10000',
    con=engine
)
# Explore and prototype:
df_sample['revenue_tier'] = pd.cut(
    df_sample['amount'],
    bins=[0, 100, 500, float('inf')],
    labels=['low', 'mid', 'high']
)
print(df_sample['revenue_tier'].value_counts())
# Production: translate cut logic to SQL CASE WHEN

pandasql: написание SQL-запросов к DataFrames

Библиотека pandasql позволяет писать SQL-запросы непосредственно к DataFrames Pandas, используя SQLite под капотом. sqldf('SELECT * FROM df WHERE amount > 100', locals()) выполняет запрос к DataFrame df. Это удобно, если Вы мыслите в терминах SQL, но данные уже находятся в Pandas, а также при изучении концепций SQL на данных в памяти. Однако для большинства операций эта библиотека медленнее встроенных средств Pandas — используйте её для удобства работы с SQL, а не для повышения производительности.

# pip install pandasql
import pandas as pd
# from pandasql import sqldf

df = pd.DataFrame({
    'product': ['A', 'B', 'A', 'C', 'B'],
    'sales': [100, 200, 150, 80, 220]
})

# With pandasql (commented out as it requires install):
# result = sqldf('SELECT product, SUM(sales) AS total FROM df GROUP BY product', locals())

# Equivalent native Pandas:
result = df.groupby('product')['sales'].sum().reset_index()
print(result)

Схема выбора: краткая памятка

Используйте это руководство при выборе между SQL и Pandas:

  • Данные находятся в базе и их много? Сначала фильтруйте и агрегируйте их в SQL.
  • Требуется пользовательская логика на Python? Используйте Pandas после предварительной фильтрации в SQL.
  • Исследовательский анализ на выборке? Pandas обеспечивает более быструю итерацию.
  • Временные ряды со сложной скользящей статистикой? Используйте rolling/ewm в Pandas.
  • Простая группировка GROUP BY для миллионов строк? Используйте SQL с индексами.
  • Несколько небольших DataFrame уже находятся в памяти? Подойдёт pd.merge().
  • Требуются транзакции ACID? Используйте базу данных SQL, а не Pandas.

Объединение обоих подходов: гибридный конвейер

Наиболее практичный подход — это гибридный конвейер, в котором каждый инструмент используется с учётом его сильных сторон. SQL отвечает за загрузку данных, грубую фильтрацию и стандартные агрегации в больших исходных таблицах. Результат — удобный для обработки DataFrame — передаётся в Pandas для конструирования признаков, пользовательских метрик, скользящих статистик и визуализации. При необходимости результаты записываются обратно в базу данных для последующего предоставления. Такой конвейер понятен, масштабируем и удобен в сопровождении для любого аналитика, знакомого и с SQL, и с Python.

import pandas as pd
import sqlalchemy as sa

engine = sa.create_engine('sqlite:///pipeline.db')

# Step 1: SQL coarse aggregation
df = pd.read_sql_query('''
    SELECT DATE(order_date) AS date, region, SUM(amount) AS daily_revenue
    FROM orders WHERE status = 'completed'
    GROUP BY DATE(order_date), region
    ORDER BY date
''', con=engine, parse_dates=['date'])

# Step 2: Pandas rolling and pivoting (hard in SQL)
df['7d_avg'] = df.groupby('region')['daily_revenue'].transform(
    lambda x: x.rolling(7, min_periods=1).mean()
)
pivot = df.pivot(index='date', columns='region', values='7d_avg')
print(pivot.tail())

Быстрая проверка

Проверьте, насколько хорошо Вы усвоили понятия анализа данных из этого урока.

Итоги урока

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

Часто задаваемые вопросы

Урок «Pandas или SQL: выбор подходящего инструмента» бесплатный?

Да — полный текст урока «Pandas или SQL: выбор подходящего инструмента» бесплатно доступен здесь в веб-версии. Чтобы практиковать его интерактивно (встроенный редактор кода и ИИ-репетитор 24/7) и разблокировать остальной курс Pandas & NumPy Academy, подпишись на CoddyKit PRO. Курс Pandas & NumPy Academy содержит 4 уроков всего.

Чему я научусь в уроке «Pandas или SQL: выбор подходящего инструмента»?

Сравните groupby/merge в Pandas с GROUP BY/JOIN в SQL и решите, на каком уровне следует выполнять каждое преобразование Ты практикуешь Pandas & NumPy Academy с помощью реального кода, который запускаешь прямо в браузере, и ИИ-репетитор 24/7 отвечает на твои вопросы во время урока.

Нужен ли мне опыт, чтобы начать Pandas & NumPy Academy?

Предыдущий опыт не требуется. Pandas & NumPy Academy на CoddyKit структурирован для всех уровней — от новичков до продвинутых, поэтому ты можешь начать отсюда или с самого начала и учиться в своем темпе. Это урок 4 из 4.

Сколько времени занимает урок «Pandas или SQL: выбор подходящего инструмента»?

Большинство уроков CoddyKit занимают около 5–10 минут. Каждый из них компактный и интерактивный, поэтому ты постоянно делаешь прогресс и продолжаешь с того же места в веб-версии и приложении.

Можно ли писать и запускать код в этом уроке Pandas & NumPy Academy?

Да. Каждый урок Pandas & NumPy Academy включает встроенный редактор кода, поэтому ты пишешь и запускаешь реальный код прямо в браузере и получаешь моментальную обратную связь от AI — локальная установка не требуется.

Все уроки этого курса

  1. Подключение к базе данных с помощью SQLAlchemy
  2. Выполнение SQL-запросов из Pandas
  3. Запись DataFrames в таблицы базы данных
  4. Pandas или SQL: выбор подходящего инструмента
← Назад к Pandas & NumPy Academy