2025, Nov 03 06:01
Визуализация ответов опроса: сгруппированные и накопленные столбцы в pandas и Seaborn
Как строить сгруппированные и накопленные столбцы для категориальных ответов опроса с разрезом по полу: Seaborn countplot и гибкий pandas crosstab, шаг за шагом.
Визуализировать категориальные ответы опроса с разбивкой по подгруппе кажется просто — пока не захочется получить сгруппированные или накопленные столбцы. Суть в том, чтобы посчитать, сколько раз встречается каждая категория, а затем выбрать способ построения под желаемый формат. Ниже — короткий разбор: либо Seaborn для сразу сгруппированного графика, либо чистый pandas для сгруппированных и накопленных вариантов.
Пример данных, иллюстрирующий задачу
Будем работать с буквенными ответами и разделением по полу. Цель — изобразить частоту каждого ответа в разрезе пола с возможностью переключаться между сгруппированными и накопленными столбцами.
import pandas as pd
choices = ['A', 'B', 'A', 'B', 'A', 'A', 'B', 'B', 'B', 'A', 'C', 'B', 'A', 'C']
sexes = ['M', 'M', 'F', 'M', 'F', 'M', 'F', 'M', 'M', 'F', 'M', 'M', 'F', 'M']
tbl = pd.DataFrame({'Choice': choices, 'Sex': sexes})
Что здесь происходит на самом деле
Нужно посчитать, сколько раз встречается каждое категориальное значение, и разложить эти количества по другой категории. Это классическая задача «подсчетов по группам». Быстрый путь — воспользоваться графиком, который агрегирует счётчики на лету, либо заранее построить частотную таблицу и уже её отрисовать. Оба подхода дают сгруппированные или накопленные столбцы без ручных циклов и самодельной группировки.
Решение 1: сгруппированные столбцы в Seaborn
Для прямого построения сгруппированного графика достаточно простого countplot. Он сам считает количество по каждой категории и группирует столбцы по параметру hue.
import seaborn as sbn
sbn.countplot(data=tbl, x='Choice', hue='Sex')
В результате получаются сгруппированные по ответам столбцы с разделением по полу.
Решение 2: сгруппированные или накопленные столбцы через pandas crosstab
Если не хочется полагаться на Seaborn, сначала посчитайте таблицу сопряжённости, а затем постройте график. Так легко переключаться между сгруппированным и накопленным видами.
# Сгруппированные столбцы
pd.crosstab(tbl['Choice'], tbl['Sex']).plot.bar()
Чтобы сложить столбцы, поменяйте один параметр:
# Накопленные столбцы
pd.crosstab(tbl['Choice'], tbl['Sex']).plot.bar(stacked=True)
Если нужна нормировка накопленного графика до процентов по строкам, используйте normalize по index перед построением:
# Накопленные столбцы, нормированные в процентах
pd.crosstab(tbl['Choice'], tbl['Sex'], normalize='index').plot.bar(stacked=True)
Почему это важно
Умение переключаться между прямой агрегацией в библиотеке визуализации и явной частотной таблицей упрощает работу с категориальными данными. countplot в Seaborn — быстрый путь к сгруппированным столбцам, а pandas crosstab даёт полный контроль над частотной таблицей, накоплением и нормировкой в одном месте. Такая гибкость экономит время при смене стиля диаграммы или когда нужны нормированные представления.
Итоги
Когда требуется подсчёт категорий по подгруппам, выбирайте подход, ориентированный на счётчики. Для быстрых сгруппированных результатов используйте countplot. Если нужны сгруппированные, накопленные или нормированные столбцы без лишних усилий — постройте crosstab и отрисуйте его. С этими двумя приёмами вы закроете типичные сценарии «A/B/C по M/F» без борьбы с ручной группировкой и поиском редких примеров по категориальным данным.
Статья основана на вопросе на StackOverflow от ArgumentClinician и ответе от mozway.