Перейти к основному содержимому

Табличные данные — Pandas, Polars, SQL и PySpark

Аналитику Разработчику

Назначение

Краткая напоминалка для работы с табличными данными: одна и та же задача формулируется по-разному в четырёх часто встречающихся инструментах.

ИнструментГде выполняетсяТипичный масштаб
PandasPython, одна машина, RAMПрототипы, EDA, файлы до объёма ОЗУ
PolarsPython (Rust-ядро), одна машинаТе же задачи, что у Pandas, но быстрее на больших таблицах в памяти
SQLСУБД (PostgreSQL, MySQL и др.)Данные уже в таблицах; фильтр и агрегация на стороне сервера
PySparkКластер Apache SparkДанные не помещаются на одном узле или нужен распределённый конвейер

Учебный контекст — Python для анализа, Data Science и Big Data. Для чистого SQL без Python — шпаргалка по SQL.

Как читать таблицу

В колонках — эквивалентные операции. Имена столбцов (column, col1, agg_col) и имя таблицы (table, table1) — плейсхолдеры. В PySpark для groupBy и агрегатов нужен импорт функций, например from pyspark.sql.functions import avg.

Сводная таблица операций

ОперацияPandasPolarsSQLPySpark
Импорт библиотеки / сессияimport pandas as pdimport polars as plfrom pyspark.sql import SparkSession
spark = SparkSession.builder.appName("app").getOrCreate()
Чтение CSVdf = pd.read_csv("data.csv")df = pl.read_csv("data.csv")PostgreSQL: COPY table FROM 'data.csv' WITH (FORMAT csv, HEADER true);
MySQL: LOAD DATA INFILE 'data.csv' INTO TABLE table FIELDS TERMINATED BY ',' LINES TERMINATED BY '\n' IGNORE 1 ROWS;
df = spark.read.csv("data.csv", header=True, inferSchema=True)
Первые k строкdf.head(10)df.head(10)SELECT * FROM table LIMIT 10;df.show(10)
Размер (строки × столбцы)df.shapedf.shapeСтроки: SELECT count(*) FROM table;
Столбцы: SELECT count(*) FROM information_schema.columns WHERE table_name = 'table';
Строки: df.count()
Столбцы: len(df.columns)
Типы столбцовdf.dtypesdf.schema или df.dtypesDESCRIBE table; (MySQL)
SELECT column_name, data_type FROM information_schema.columns WHERE table_name = 'table'; (PostgreSQL)
df.printSchema()
Выбор столбцовdf[["col1", "col2"]]df.select("col1", "col2")SELECT col1, col2 FROM table;df.select("col1", "col2")
Фильтр строкdf[df["column"] > 10]df.filter(pl.col("column") > 10)SELECT * FROM table WHERE column > 10;df.filter(df["column"] > 10)
Сортировкаdf.sort_values("column")df.sort("column")SELECT * FROM table ORDER BY column;df.orderBy("column")
Заполнить пропускиdf["column"].fillna(0)df.with_columns(pl.col("column").fill_null(0))UPDATE table SET column = 0 WHERE column IS NULL;df.fillna(0) или df.na.fill(0)
Соединение таблицpd.merge(df1, df2, on="col", how="inner")df1.join(df2, on="col", how="inner")SELECT * FROM table1 INNER JOIN table2 ON table1.col = table2.col;df1.join(df2, on="col", how="inner")
Объединить строки (stack)pd.concat([df1, df2])pl.concat([df1, df2])SELECT * FROM table1 UNION ALL SELECT * FROM table2;df1.union(df2)
Группировка и среднееdf.groupby("column")["agg_col"].mean()df.group_by("column").agg(pl.mean("agg_col"))SELECT column, avg(agg_col) FROM table GROUP BY column;df.groupBy("column").agg(avg("agg_col"))
Уникальные значенияdf["column"].unique()df["column"].unique()SELECT DISTINCT column FROM table;df.select("column").distinct()
Переименовать столбецdf.rename(columns={"old_name": "new_name"})df.rename({"old_name": "new_name"})PostgreSQL: ALTER TABLE table RENAME COLUMN old_name TO new_name;df.withColumnRenamed("old_name", "new_name")
Удалить столбецdf.drop(columns=["column"])df.drop("column")ALTER TABLE table DROP COLUMN column;df.drop("col1", "col2")

Когда какой инструмент

Pandas — де-факто стандарт для учебных ноутбуков и быстрого EDA: богатая экосистема, много примеров в сети. Ограничение — данные должны помещаться в память одного процесса.

Polars — тот же класс задач (таблица в RAM), но вычисления на Rust и ленивые планы в LazyFrame часто дают кратный выигрыш по скорости. Синтаксис ближе к Spark/SQL, чем к классическому Pandas.

SQL — когда данные уже лежат в СУБД и переносить миллионы строк в Python невыгодно. Агрегации, join и фильтры выполняет оптимизатор базы; Python подключается через read_sql / драйвер или ORM.

PySpark — когда одной машины мало: кластер, HDFS/S3, потоковая обработка, единый движок с Spark SQL. API DataFrame сознательно похож на Pandas, но вычисления ленивые до вызова действия (.count(), .show(), .write).


Частые отличия (не в таблице)

  • Соединение таблиц: в Pandas pd.merge(..., how="inner"|"left"|"right"|"outer"), в Polars и PySpark join(..., how=…) — те же четыре режима, что INNER, LEFT, RIGHT и FULL OUTER в SQL. Разбор на двух таблицах с ключами 1–4 — четыре основных JOIN.
  • Пропуски: в Pandas — NaN (fillna); в Polars — null (fill_null) и отдельно NaN для float (fill_nan). В SQL — IS NULL.
  • Индекс: у Pandas есть именованный индекс строк; у Polars и Spark DataFrame — только столбцы (плюс служебные метаданные).
  • Копия и view: в Pandas срезы иногда дают view на те же данные; в Polars и Spark неизменяемость и план выполнения устроены иначе — ориентируйтесь на явные .copy() / новые DataFrame.
  • Union в Spark: схемы df1 и df2 должны совпадать по именам и совместимым типам.

См. также

См. также

Другие статьи этого же раздела в боковом меню (как на странице "О разделе").