Перейти к содержанию

252 уроков, 17 библиотек и челлендж «Что выведет код?» — бесплатно, код прямо в браузере

Начать обучение
Урок 3 из 20 Средний 25 мин 110 XP

countplot в Seaborn: сколько чего встречается в данных

countplot рисует частоты категорий из сырых строк таблицы: без value_counts и без ручного plt.bar. Лог заказов, календарный порядок дней и горизонтальный вариант — за один урок.

Редакция Питоники

Интернет-магазин запустил акцию в субботу, и лог заказов за неделю начался не с понедельника, а как придётся. Вопрос владельца: в какие дни заказов больше? В таблице нет столбца «число заказов» — есть только день в каждой строке. Ответ придётся посчитать, и countplot сделает это за вас.

Сырые данные: лог заказов

Лог заказов: 12 строк
import pandas as pd

orders = pd.DataFrame({
    "order_id": [101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112],
    "day": ["Сб", "Сб", "Вс", "Пн", "Пн", "Вт", "Вт", "Ср", "Чт", "Пт", "Пт", "Вс"],
})

print(orders)
Вывод
    order_id day
0        101  Сб
1        102  Сб
2        103  Вс
3        104  Пн
4        105  Пн
5        106  Вт
6        107  Вт
7        108  Ср
8        109  Чт
9        110  Пт
10       111  Пт
11       112  Вс

Двенадцать заказов, столбец day — и всё. Это типичная сырая таблица: один заказ — одна строка, агрегатов нет. Именно такие таблицы приходят из баз, логов и форм, и именно для них Seaborn придуман: график получает сырые строки, а не заранее посчитанные итоги.

Путь Matplotlib: сначала value_counts, потом bar

До Seaborn ответ собирался в два хода: сначала посчитать частоты в pandas, потом нарисовать их столбцами. Первый ход выглядит так:

Подсчёт вручную: value_counts
import pandas as pd

orders = pd.DataFrame({
    "order_id": [101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112],
    "day": ["Сб", "Сб", "Вс", "Пн", "Пн", "Вт", "Вт", "Ср", "Чт", "Пт", "Пт", "Вс"],
})

print(orders["day"].value_counts())
Вывод
day
Сб    2
Вс    2
Пн    2
Вт    2
Пт    2
Ср    1
Чт    1
Name: count, dtype: int64

value_counts посчитал и отсортировал: по два заказа в субботу, воскресенье, понедельник, вторник и пятницу, по одному — в среду и четверг. Второй ход — plt.bar по этим числам с ручными подписями. Seaborn склеивает оба хода в одну строку.

countplot считает сам

Заказы по дням: одна строка
import pandas as pd
import seaborn as sns
import matplotlib.pyplot as plt

orders = pd.DataFrame({
    "order_id": [101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112],
    "day": ["Сб", "Сб", "Вс", "Пн", "Пн", "Вт", "Вт", "Ср", "Чт", "Пт", "Пт", "Вс"],
})

sns.set_theme()
ax = sns.countplot(data=orders, x="day")
ax.set_title("Заказы по дням недели")
ax.set_xlabel("")
ax.set_ylabel("Число заказов")
plt.show()
Вывод
График отображается под редактором

countplot не потребовал ни y=, ни подсчётов: он сам прошёлся по столбцу day и нарисовал по столбцу на каждую встретившуюся категорию. Высота столбца — число строк с этим значением, ровно то, что считал value_counts. Единственная странность — порядок: столбцы идут Сб, Вс, Пн, Вт... — в порядке появления строк в логе. Лог начинался с субботы, и график послушно начался с неё.

order: дни недели по календарю

Порядок Пн–Вс через order
import pandas as pd
import seaborn as sns
import matplotlib.pyplot as plt

orders = pd.DataFrame({
    "order_id": [101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112],
    "day": ["Сб", "Сб", "Вс", "Пн", "Пн", "Вт", "Вт", "Ср", "Чт", "Пт", "Пт", "Вс"],
})

sns.set_theme()
week_order = ["Пн", "Вт", "Ср", "Чт", "Пт", "Сб", "Вс"]
ax = sns.countplot(data=orders, x="day", order=week_order)
ax.set_title("Заказы по дням недели: календарный порядок")
ax.set_xlabel("")
ax.set_ylabel("Число заказов")
plt.show()
Вывод
График отображается под редактором

Параметр order= получил список категорий — и теперь неделя читается слева направо, как в календаре. Это тот же order, что сортировал города в уроке про barplot: порядок графика не должен зависеть от порядка строк в таблице. Отдельный бонус: если в данные попадёт день, которого нет в order, столбца для него не будет — порядок становится и фильтром.

Горизонтальный countplot: y= вместо x=

Горизонтальный вариант
import pandas as pd
import seaborn as sns
import matplotlib.pyplot as plt

orders = pd.DataFrame({
    "order_id": [101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112],
    "day": ["Сб", "Сб", "Вс", "Пн", "Пн", "Вт", "Вт", "Ср", "Чт", "Пт", "Пт", "Вс"],
})

sns.set_theme()
ax = sns.countplot(data=orders, y="day", order=["Пн", "Вт", "Ср", "Чт", "Пт", "Сб", "Вс"])
ax.set_title("Заказы по дням: горизонтально")
ax.set_xlabel("Число заказов")
ax.set_ylabel("")
plt.show()
Вывод
График отображается под редактором

Замена x="day" на y="day" развернула диаграмму: категории легли на вертикальную ось, частоты ушли вправо. Практическое правило: длинные подписи категорий (названия магазинов, товары, адреса) лучше читаются горизонтально — их не приходится поворачивать и ужимать. Для семи коротких дней оба варианта равноправны, выбирайте тот, что лучше встаёт в отчёт.

Что дальше

Вы научились считать категории из сырых данных одной строкой и управлять их порядком. Следующий урок — histplot: та же задача «сколько чего», только для чисел, которые режутся на интервалы, — и первая встреча с формой распределения.

countplot принимает сырые строки и сам делает то, что в Matplotlib было двумя ходами: value_counts, а затем bar с ручными подписями.

Что выведет код?

Сначала предскажи ответ в голове — это главный навык программиста.

import pandas as pd

orders = pd.DataFrame({"day": ["Сб", "Пн", "Сб", "Вт", "Пн", "Сб"]})
print(orders["day"].value_counts())
import pandas as pd
import seaborn as sns

orders = pd.DataFrame({"day": ["Пн", "Вт", "Ср", "Пн", "Вт", "Пн"]})
ax = sns.countplot(data=orders, x="day")
print(len(ax.patches))
Проверь себя
0 / 5

1. Что рисует sns.countplot(data=orders, x="day")?

2. В логе строки начинаются с субботы, а на графике нужна неделя Пн–Вс. Как это сделать?

3. Как развернуть countplot горизонтально?

4. Чем countplot отличается от barplot?

5. В данных есть «Сб» и «Вс», но в order передали только ["Пн", ..., "Пт"]. Что окажется на графике?

Карточки терминов
Запомнено: 0 / 6
Практика

По логу заказов (заготовка ниже) постройте countplot заказов по дням недели в календарном порядке: от Пн до Вс. Подпишите ось Y «Число заказов».

practice.py
Вопросы и ответы по уроку

Чем seaborn countplot отличается от barplot?

countplot отвечает на вопрос «сколько раз встретилась категория»: ему нужен только категориальный столбец, частоты он считает сам. barplot отвечает «сколько в среднем у категории»: ему нужен числовой столбец y=, он считает среднее и добавляет доверительный интервал. Перепутать просто: sum и count — разные вопросы.

Урок 2: barplot — средние по категориям

Как отсортировать столбцы countplot по частоте?

Соберите порядок из value_counts: order=orders["day"].value_counts().index — категории выстроятся от частой к редкой. Для фиксированного порядка вроде Пн–Вс передайте список явно: order=["Пн", "Вт", "Ср", "Чт", "Пт", "Сб", "Вс"].

Когда countplot лучше делать горизонтальным?

Когда подписи категорий длинные — названия магазинов, товаров, адресов: на вертикальной оси они читаются целиком, без поворота и ужимания. Замените x= на y=, а подписи частот и категорий поменяйте местами: горизонтальной становится ось значений.

Почему на countplot не все дни недели, хотя они есть в данных?

Если задан параметр order, он работает и как фильтр: категории вне списка не рисуются. Проверьте список в order — вероятно, в нём не все значения столбца. Без order рисуются все встретившиеся категории в порядке появления в данных.

Понравился урок? Сошлитесь на него

«countplot — это гистограмма для строк: по столбцу на каждую категорию, высота — сколько раз она встретилась.»

Скопируйте готовую ссылку в формате HTML, Markdown или чистый адрес и вставьте в статью на Habr, VC, Telegram-канал или свой блог — так о проекте узнают новые читатели.

TelegramVK

Похожие уроки по темам

Подобраны автоматически по пересечению тем и ключевых слов.