Нашли ошибку?
Скачать чистый
урок 3 из 5≈ 20 минупражнения: 0 из 4

Результат группировки

Превратить результат группировки в обычную таблицу — reset_index и as_index=False; фильтровать и сортировать группы; найти лучших и худших внутри каждой группы — сортировка и groupby(...).head(n).

Python запустится при первом выполнении

Группировка редко бывает последним шагом. Её результат обычно нужно отсортировать, отфильтровать, соединить с другой таблицей или показать в отчёте. Для этого удобнее обычная таблица — с названиями групп в столбце, а не в индексе.

Из индекса — в столбец

Результат группировки — Series: города стали метками индекса.

[ ]Города — в индексе
import pandas as pd

orders = pd.read_csv("data/shop_orders.csv")
orders["revenue"] = orders["price"] * orders["quantity"]
by_city = orders.groupby("city")["revenue"].sum()
by_city
Выводсохранённый · нажмите «Выполнить», чтобы получить свой
city
Екатеринбург        423350
Казань              440150
Москва             1310110
Новосибирск         324090
Санкт-Петербург     803720
Name: revenue, dtype: int64

Знакомый reset_index без drop=True не выбрасывает старый индекс, а делает его обычным столбцом:

[ ]Города — в столбце
by_city.reset_index()
Выводсохранённый · нажмите «Выполнить», чтобы получить свой
city revenue
0 Екатеринбург 423350
1 Казань 440150
2 Москва 1310110
3 Новосибирск 324090
4 Санкт-Петербург 803720

Получилась таблица из двух столбцов с обычным индексом 0, 1, 2… Того же добиваются сразу — параметром as_index=False в groupby («не делать ключ индексом»):

[ ]То же одной командой
orders.groupby("city", as_index=False)["revenue"].sum()
Выводсохранённый · нажмите «Выполнить», чтобы получить свой
city revenue
0 Екатеринбург 423350
1 Казань 440150
2 Москва 1310110
3 Новосибирск 324090
4 Санкт-Петербург 803720

У результата size() нет названия, и столбец с числами получил бы имя 0. Название задаёт параметр name в reset_index:

[ ]Число строк по городам — таблицей
orders.groupby("city").size().reset_index(name="lines")
Выводсохранённый · нажмите «Выполнить», чтобы получить свой
city lines
0 Екатеринбург 312
1 Казань 341
2 Москва 948
3 Новосибирск 258
4 Санкт-Петербург 589
[ ]Упражнение 1Таблица категорий решено

Сохраните в category_table таблицу из двух столбцов — category и revenue (сумма выручки по категории). Строки — по убыванию выручки, индекс — с нуля подряд.

category_table = ...

Два ключа — плоская таблица

Особенно удобен as_index=False при группировке по двум столбцам: вместо индекса из двух уровней получается простая «длинная» таблица — по строке на каждую пару.

[ ]Пары «город, канал» — строками
pairs = orders.groupby(["city", "channel"], as_index=False)["revenue"].sum()
pairs.head(4)
Выводсохранённый · нажмите «Выполнить», чтобы получить свой
city channel revenue
0 Екатеринбург маркетплейс 83080
1 Екатеринбург приложение 150240
2 Екатеринбург сайт 190030
3 Казань маркетплейс 113670

С ней работают обычными приёмами — например, фильтром:

[ ]Пары с выручкой больше 300 тысяч
pairs[pairs["revenue"] > 300000]
Выводсохранённый · нажмите «Выполнить», чтобы получить свой
city channel revenue
6 Москва маркетплейс 343390
7 Москва приложение 334240
8 Москва сайт 632480
14 Санкт-Петербург сайт 339660
Вопрос

Что выведет print(orders.groupby(["city", "channel"], as_index=False)["revenue"].sum().shape)?

[ ]Упражнение 2Слабые места решено

Сохраните в pair_table таблицу по парам «город, канал» со столбцами city, channel, total (выручка) и orders (число разных заказов). В weak сохраните пары, где заказов меньше 55, — от меньшего числа заказов к большему.

pair_table = ...
weak = ...

Лучшие в каждой группе

«Два самых продаваемых товара в каждой категории» — частый вопрос. nlargest(2) здесь не подходит: он вернёт два товара на всю таблицу. Решение — в два шага.

Шаг первый: посчитать выручку каждого товара и отсортировать всю таблицу по убыванию.

[ ]Товары по убыванию выручки
products = orders.groupby(["category", "product"], as_index=False)["revenue"].sum()
products = products.sort_values("revenue", ascending=False)
products.head(5)
Выводсохранённый · нажмите «Выполнить», чтобы получить свой
category product revenue
7 Кофе Эфиопия 250 г 426600
3 Кофе Бразилия 1 кг 375390
6 Кофе Эспрессо-смесь 1 кг 372650
4 Кофе Колумбия 250 г 372600
5 Кофе Кофе без кофеина 250 г 367200

Шаг второй: сгруппировать по категории и взять head(2). После groupby метод head берёт первые строки каждой группы — а раз таблица отсортирована, первые и есть лучшие:

[ ]По два лучших товара в категории
products.groupby("category").head(2)
Выводсохранённый · нажмите «Выполнить», чтобы получить свой
category product revenue
7 Кофе Эфиопия 250 г 426600
3 Кофе Бразилия 1 кг 375390
18 Чай Улун 100 г 194940
16 Чай Зелёный чай 100 г 167700
9 Посуда Турка медная 139200
10 Посуда Френч-пресс 111510
0 Аксессуары Кофемолка ручная 102400
13 Сладости Миндаль в шоколаде 82880
12 Сладости Зефир 53760
1 Аксессуары Термокружка 48300

Строки остались в порядке общей сортировки. Чтобы категории шли подряд, результат сортируют ещё раз:

[ ]Категории — по порядку
products.groupby("category").head(2).sort_values(["category", "revenue"], ascending=[True, False])
Выводсохранённый · нажмите «Выполнить», чтобы получить свой
category product revenue
0 Аксессуары Кофемолка ручная 102400
1 Аксессуары Термокружка 48300
7 Кофе Эфиопия 250 г 426600
3 Кофе Бразилия 1 кг 375390
9 Посуда Турка медная 139200
10 Посуда Френч-пресс 111510
13 Сладости Миндаль в шоколаде 82880
12 Сладости Зефир 53760
18 Чай Улун 100 г 194940
16 Чай Зелёный чай 100 г 167700

Обратите внимание: head после groupby не сворачивает группы в одну строку, как sum, а возвращает сами строки таблицы. Парный метод tail(n) берёт последние строки каждой группы.

[ ]Упражнение 3Аутсайдеры решено

Таблица products отсортирована по убыванию выручки. Сохраните в worst товар с наименьшей выручкой в каждой категории: пять строк, отсортированных по категории, с индексом с нуля.

worst = ...

[ ]Упражнение 4Лучшие покупатели городов решено

Сохраните в customers таблицу со столбцами city, customer_id, revenue — выручку по каждому покупателю с его городом. В vip сохраните двух покупателей с наибольшей выручкой в каждом городе: десять строк, отсортированных по городу, а внутри города — по убыванию выручки; индекс с нуля.

customers = ...
vip = ...

Итоги

  • reset_index() после группировки или as_index=False в groupby — ключи становятся столбцами.
  • С двумя ключами as_index=False даёт плоскую таблицу: строка на каждую пару.
  • Лучшие в каждой группе: отсортировать всю таблицу, затем groupby("ключ").head(n).
  • head и tail после groupby возвращают строки, а не итоги.

Подробнее в справочнике

Нашли ошибку?