pandas: группировки, соединения и упорядоченные показатели

groupby и agg: сводные показатели с явными именами агрегатов

Содержание курса

Два способа получить плоскую таблицу: as_index=False и reset_index()

Мы уже видели, что groupby по умолчанию превращает ключ группировки в индекс результата. Это становится проблемой, как только хочешь работать с результатом как с обычной таблицей: фильтровать по ключу, сортировать или передавать дальше по пайплайну. Посмотрим, как это проявляется на практике и как это исправить.

Ловушка: ключ пропал из columns

Если вызываешь groupby без as_index=False, ключ группировки уходит в индекс и исчезает из result.columns:

import pandas as pd

df = pd.DataFrame({
    'region':   ['Север', 'Юг', 'Север', 'Юг', 'Север'],
    'category': ['A', 'A', 'B', 'B', 'A'],
    'sales':    [100, 200, 150, 300, 80],
    'units':    [10, 20, 15, 30, 8]
})

result = df.groupby('region').agg(
    total_sales=('sales', 'sum'),
    avg_units=('units', 'mean')
)

print(result.columns.tolist())
# ['total_sales', 'avg_units']

print(result.index.name)
# region

region есть — но только в индексе. В columns его нет. Если попробуешь написать result['region'], получишь KeyError. Именно здесь ломаются скрипты, где после агрегации ожидается обычная плоская таблица.

Способ 1: as_index=False прямо в groupby

Простейшее решение — передать параметр сразу:

result1 = df.groupby('region', as_index=False).agg(
    total_sales=('sales', 'sum'),
    avg_units=('units', 'mean')
)

print(result1)
#   region  total_sales  avg_units
# 0  Север          330       11.0
# 1    Юг           500       25.0

print(result1.columns.tolist())
# ['region', 'total_sales', 'avg_units']

region возвращается в обычные столбцы, индекс — стандартный RangeIndex. Таблица сразу готова к любым операциям.

Способ 2: reset_index() после agg

Если по каким-то причинам написал groupby без as_index=False, можно добавить reset_index() в конце цепочки:

result2 = df.groupby('region').agg(
    total_sales=('sales', 'sum'),
    avg_units=('units', 'mean')
).reset_index()

print(result2)
#   region  total_sales  avg_units
# 0  Север          330       11.0
# 1    Юг           500       25.0

Результат идентичен. reset_index() вынимает ключ из индекса и помещает его первым столбцом — именно то, что делает as_index=False автоматически.

Какой способ выбирать

Оба способа корректны и дают одинаковую таблицу. На практике as_index=False лаконичнее: параметр виден сразу при чтении строки с groupby, и не нужно помнить о дополнительном вызове в конце. reset_index() полезен, когда получаешь уже сгруппированный результат и хочешь его «распрямить» постфактум.

В этом курсе для группировки по одному ключу оба варианта используются; для нескольких ключей — только as_index=False, чтобы не сталкиваться с составными типами индекса.

Начать заново?

Помощник начнёт новый диалог по этой задаче. Текущая переписка останется в истории до конца срока хранения.

О переписке

Можно приложить до трёх фото PNG, JPEG или WebP по 5 МБ.

Переписка и фото хранятся 90 дней после последнего принятого сообщения. Преподаватель получит доступ к диалогу, когда вы попросите его помочь.

Проверка решения остаётся отдельным действием.