Создание Pivot-таблиц в Python с помощью Pandas

Pivot-таблицы остаются одним из самых популярных инструментов в MS Excel. Аналитики, инженеры данных и активные пользователи часто обращаются к Excel за быстрыми сводками. Однако те же возможности легко воспроизвести и расширить в Python — особенно с библиотекой Pandas.
В этой статье подробно разберём, как создавать и настраивать pivot-таблицы в Pandas, когда выбирать pivot_table, а когда воспользоваться groupby или crosstab, как добавлять итоги, несколько функций агрегации, как работать с несколькими индексами и как экспортировать результат.
Основные требования
Перед началом убедитесь, что у вас установлены:
- Python (рекомендуется 3.8+)
- Pandas
- IDE: Jupyter Notebook, VS Code, PyCharm или другая удобная среда
- Набор данных в Excel или CSV — в примерах будет использоваться «Sample - Superstore» (ссылка/локальный файл).
Данные примеры рассчитаны на типичный набор «продажи/регионы/категории», но сами приёмы универсальны.
Ссылка на пример данных: Sample Superstore
Импорт необходимых библиотек и данных
Для работы понадобится Pandas. Импорт и чтение Excel-файла в DataFrame:
import pandas as pd
# Замените путь и имя файла на свои
path = "C://Users//user/OneDrive//Desktop//"
file = "Sample - Superstore.xls"
df = pd.read_excel(path + file)
# Просмотр первых 5 строк
df.head()Функция head() помогает проверить, что данные корректно загружены: типы колонок, наличие пустых значений и ожидаемые названия столбцов.
Понятия и соответствия с Excel
- Data — исходные данные в DataFrame (df)
- Values — столбцы, по которым вычисляются агрегаты (например, Sales)
- Index — столбец(ы) для группировки (аналог строк в Excel-пивоте)
- Columns — столбцы для дополнительной разбивки (аналог колонок в Excel-пивоте)
Pandas реализует pivot-операции через df.pivot_table, df.pivot (более строгое преобразование), pd.crosstab и groupby. pivot_table — наиболее гибкий для агрегаций.
Простой pivot_table по одному индексу
Чтобы получить агрегированные значения по столбцу Segment:
# Пример: среднее по всем числовым колонкам для каждой группы Segment
df.pivot_table(index="Segment")Где:
- index — имя колонки для группировки
- По умолчанию pivot_table берёт для вычислений все числовые столбцы и применяет aggfunc=”mean”.
Множественные индексы (MultiIndex)
Для вложенной группировки можно передать список колонок в index:
df.pivot_table(index=["Category", "Sub-Category"])Это создаст иерархический индекс (MultiIndex), где сначала будет Category, затем Sub-Category. Результат показывает среднее для каждого числового столбца.
Совет: при отображении в интерфейсах без поддержки MultiIndex можно вызвать .reset_index() или .rename_axis(None).
Ограничение значений через values
По умолчанию Pandas агрегирует все числовые столбцы. Чтобы выбрать конкретные столбцы, используйте параметр values:
df.pivot_table(index=["Region", "Category", "Sub-Category"], values="Sales")В результате вы получите среднее (по умолчанию) значение продаж (Sales) для каждой комбинации Region → Category → Sub-Category.
Несколько функций агрегации
Чтобы вычислить разные агрегаты одновременно (сумму, максимум, минимум, количество):
df.pivot_table(index=["Category"], values="Sales", aggfunc=[sum, max, min, len])Обратите внимание:
- len возвращает количество элементов в группе
- aggfunc может содержать список функций, одну функцию или словарь {колонка: [функции]}
Пример с разными функциями для разных столбцов:
df.pivot_table(
index=["Region"],
values=["Sales", "Profit"],
aggfunc={"Sales": sum, "Profit": "mean"}
)Добавление итогов (Grand Totals)
Чтобы добавить общий итог по каждой агрегируемой колонке, используйте margins и margins_name:
df.pivot_table(
index=["Category"],
values="Sales",
aggfunc=[sum, max, min, len],
margins=True,
margins_name='Grand Totals'
)margins=True добавляет строку с итогом; margins_name задаёт её подпись.
Полный пример кода
import pandas as pd
path = "C://Users//user/OneDrive//Desktop//"
file = "Sample - Superstore.xls"
df = pd.read_excel(path + file)
pivot = df.pivot_table(
index=["Region", "Category", "Sub-Category"],
values="Sales",
aggfunc=[sum, max, min, len],
margins=True,
margins_name='Grand Totals'
)
print(pivot)Когда pivot_table не подходит: коротко и по делу
- Нужна артикулированная сводная таблица с уникальными сочетаниями: можно использовать df.pivot (но он требует уникальных индексов и столбцов).
- Выполняются сложные агрегаты/фильтрация на лету: иногда groupby + agg даёт больше контроля.
- Нужно пересчитать агрегаты с кастомной логикой для каждой строки: лучше использовать groupby и функцию apply.
Частые расширенные задачи и советы
- Плоский DataFrame вместо MultiIndex
pivot = df.pivot_table(...)
pivot_flat = pivot.reset_index() # перемещает уровни индекса в столбцы
# если колонки стали MultiIndex после нескольких aggfunc — можно объединить их
pivot_flat.columns = ["_" .join(map(str, col)).strip() for col in pivot_flat.columns.values]- Переименование колонок итогов и функций
Когда вы используете несколько функций, Pandas создаёт MultiIndex колонок. Чтобы получить удобные имена, применяйте list comprehension или map.
- Обработка пропусков
Перед агрегированием рекомендуется:
- df.dropna(subset=[“Sales”]) — удалить строки без ключевых метрик
- df.fillna(0) — заменить NaN на 0, если это уместно
- Производительность на больших данных
- Приведите категориальные столбцы к типу category: df[‘Region’] = df[‘Region’].astype(‘category’)
- Если данные очень велики, рассмотрите dask.dataframe или модуль polars для более быстрой агрегации.
- Временные группы (например, по месяцу)
df['Order Date'] = pd.to_datetime(df['Order Date'])
df['Order Month'] = df['Order Date'].dt.to_period('M')
df.pivot_table(index='Order Month', values='Sales', aggfunc=sum)- Экспорт результата
pivot.to_excel("pivot_result.xlsx")
# или сохранить в CSV
pivot.reset_index().to_csv("pivot_result.csv", index=False)pivot_table vs groupby vs crosstab: практическое правило
- Используйте pivot_table для классических сводных таблиц с возможностью задать несколько aggfunc и margins.
- groupby + agg подходит для кастомных агрегатов, преобразований на уровне групп и более сложной логики.
- pd.crosstab удобен для подсчёта частот и перекрёстных сводок (часто для категориальных переменных).
Решающее дерево (как выбрать метод)
flowchart TD
A[Нужно агрегировать данные?] --> B{Есть ли необходимость в
многомерной таблице 'rows и columns'?}
B -- Да --> C[Используйте pivot_table]
B -- Нет --> D{Нужна ли
кастомная логика/apply?}
D -- Да --> E[Используйте groupby + agg/apply]
D -- Нет --> F{Это подсчёт частоты/таблица сопряжённости?}
F -- Да --> G[Используйте pd.crosstab]
F -- Нет --> H[Используйте groupby]Ролевые чек-листы при работе с pivot-таблицами
Аналитик:
- Проверить типы колонок (dates, numeric, category)
- Очистить пропуски в ключевых метриках
- Сформировать pivot с нужными aggfunc и назвать итоговые столбцы
- Проверить граничные группы (пустые, редкие значения)
Инженер данных:
- Оптимизировать типы данных (category, datetime)
- Обработать дублирующие записи
- Настроить pipeline экспорта (Excel/CSV/Parquet)
Менеджер/стейкхолдер:
- Убедиться, что итоговые метрики соответствуют бизнес-определениям (например, что Sales — net или gross)
- Согласовать уровень агрегации (дни/месяцы/регионы)
Критерии приёмки
- Результат содержит все ожидаемые группы в index и columns.
- Для каждой группы посчитаны корректные агрегаты (сравнить с контрольными суммами через groupby).
- Итоговая таблица без неожиданных NaN (или NaN согласованы с бизнес-правилами).
- Если экспорт в Excel — файл открывается и содержит заголовки.
Кейс: несколько агрегаций и удобные имена колонок
Пример создания pivot с разными агрегатами и упрощением имён колонок:
p = df.pivot_table(
index=['Region', 'Category'],
values=['Sales', 'Profit'],
aggfunc={'Sales': [sum, 'mean'], 'Profit': ['mean', 'max']},
margins=True
)
# Плоские имена
p.columns = ["_".join([str(el) for el in col if el]) for col in p.columns]
p = p.reset_index()Тестовые случаи и приёмка
Примеры тестов, которые полезно выполнить для проверки корректности:
- Сопоставить итог по Sales в pivot с суммой Sales по всему DataFrame: pivot[‘Sales_sum’].loc[‘Grand Totals’] == df[‘Sales’].sum()
- Для выборочной группы вручную вычислить среднее и сравнить с pivot
- Проверить поведение при пустых Sales (удаляются/игнорируются) в зависимости от политики
Частые ошибки и решения
- Ошибка ValueError: If using pivot, необходимо иметь уникальные комбинации index/columns — решение: использовать pivot_table с aggfunc или предварительно агрегировать через groupby.
- Некорректные типы дат — предварительно привести через pd.to_datetime.
- Очень медленная агрегация на больших данных — использовать категориальные типы или инструменты как Dask / Polars.
Краткий глоссарий
- Pivot-таблица: сводка данных по выбранным измерениям (индексам) и метрикам (значениям).
- MultiIndex: многоуровневый индекс в Pandas для вложенных группировок.
- aggfunc: функция агрегации (sum, mean, max, len и др.).
Заключение
Pandas предоставляет гибкие и мощные средства для создания pivot-таблиц, которые легко интегрируются в ETL-процессы, скрипты аналитики и отчётность. Освоив базовые параметры index, values, aggfunc и margins, вы сможете формировать отчёты, экпортировать их и адаптировать под любые требования бизнеса. Для больших объёмов данных подумайте о предварительной оптимизации типов или использовании распределённых/ускоренных движков.
В следующих шагах: протестируйте приведённые примеры на своих данных, попробуйте заменить aggfunc на пользовательские функции через groupby, и посмотрите на производительность при изменении типов столбцов.
Important: всегда сверяйте агрегаты с исходными данными на контрольных выборках.
Ключевые понятия и команды сохраните в виде шпаргалки: pivot_table, reset_index, aggfunc, margins, to_excel. Удачи в анализе!
Похожие материалы
Добавить режим энергосбережения в Пункт управления iPhone
Отключить доступ приложений Facebook
Резервная копия аккаунтов в соцсетях
Как управлять закладками в Safari на iPhone
Снимать RAW на Samsung Galaxy — руководство