crosstab для таблиц частот
Вычисляйте перекрёстную таблицу частот или долей для двух категориальных столбцов с помощью pd.crosstab.
«crosstab для таблиц частот» — бесплатный урок Pandas & NumPy Academy на CoddyKit. Это урок 4 из 4. Ты можешь прочитать весь урок бесплатно ниже — а потом практиковать его прямо в браузере с встроенным редактором кода и ИИ-репетитором 24/7. Это часть пути обучения Pandas & NumPy Academy, и твой прогресс синхронизируется между веб-версией и приложением CoddyKit. Курс Pandas & NumPy Academy содержит 4 уроков всего.
Что такое перекрёстная таблица?
Перекрёстная таблица (crosstab) подсчитывает, сколько раз в наборе данных встречается каждая комбинация значений двух или более категориальных переменных. Это частный случай сводной таблицы, предназначенный именно для подсчёта. Pandas предоставляет pd.crosstab() как краткий способ вычислять такие таблицы частот без явного вызова groupby() или pivot_table().
Базовый вызов crosstab()
Минимальный вызов pd.crosstab(index, columns) принимает два входа, подобных массивам (обычно столбцы DataFrame), и возвращает таблицу частот. Строки соответствуют уникальным значениям первого аргумента, а столбцы — уникальным значениям второго. В каждой ячейке содержится количество строк, в которых оба значения встречаются вместе в исходных данных.
import pandas as pd
df = pd.DataFrame({
'gender': ['M', 'F', 'M', 'F', 'M', 'F', 'M'],
'product': ['A', 'A', 'B', 'B', 'A', 'B', 'B']
})
ct = pd.crosstab(df['gender'], df['product'])
print(ct)
# product A B
# gender
# F 1 2
# M 2 2Настройка имён строк и столбцов
Используйте параметры rownames и colnames, чтобы задать содержательные имена для осей строк и столбцов в результате вместо стандартных имён Series. Это полезно, если исходные имена столбцов в DataFrame сами по себе не объясняют смысл таблицы.
ct = pd.crosstab(
df['gender'], df['product'],
rownames=['Customer Gender'],
colnames=['Purchased Product']
)
print(ct)
# Purchased Product A B
# Customer Gender
# F 1 2
# M 2 2Добавление итогов (итоги строк и столбцов)
Передайте margins=True, чтобы добавить строку и столбец с итогами по всем значениям. По умолчанию метка итогов — 'All', но её можно изменить с помощью margins_name. Строка итогов показывает общее количество по каждому столбцу, столбец итогов — общее количество по каждой строке, а нижняя правая ячейка содержит общий итог.
ct = pd.crosstab(df['gender'], df['product'],
margins=True, margins_name='Total')
print(ct)
# product A B Total
# gender
# F 1 2 3
# M 2 2 4
# Total 3 4 7Нормализация до долей
Передайте параметр normalize, чтобы преобразовать количества в доли. normalize=True или normalize='all' делит значения на общий итог. normalize='index' вычисляет доли по строкам (сумма каждой строки равна 1.0). normalize='columns' вычисляет доли по столбцам (сумма каждого столбца равна 1.0). Доли информативнее исходных количеств, когда размеры групп различаются.
# Row proportions: what fraction of each gender bought each product?
print(pd.crosstab(df['gender'], df['product'], normalize='index').round(2))
# product A B
# gender
# F 0.33 0.67
# M 0.50 0.50
# All proportions: each cell as fraction of grand total
print(pd.crosstab(df['gender'], df['product'], normalize=True).round(2))Агрегирование значений вместо подсчёта
По умолчанию crosstab подсчитывает строки. Вместо этого можно агрегировать числовой столбец, передав параметры values и aggfunc, — аналогично pivot_table(). Например, можно вычислить общий доход для каждой комбинации пола и продукта. Благодаря этому crosstab почти эквивалентен pivot_table, но имеет немного более краткий синтаксис для создания таблиц частот.
df['revenue'] = [100, 80, 150, 120, 200, 90, 130]
# Sum revenue by gender and product instead of counting
ct_rev = pd.crosstab(
df['gender'], df['product'],
values=df['revenue'],
aggfunc='sum'
)
print(ct_rev)
# product A B
# gender
# F 80 210
# M 300 280Многоуровневая перекрёстная таблица
Передайте список в index или columns, чтобы создать перекрёстную таблицу с несколькими уровнями строк или столбцов. В результате будет MultiIndex, обеспечивающий более подробную разбивку. Например, перекрёстная таблица с полом и регионом в строках и продуктом в столбцах показывает каждую комбинацию пола, региона и продукта.
df['region'] = ['East', 'West', 'East', 'West', 'East', 'East', 'West']
ct_multi = pd.crosstab(
[df['gender'], df['region']],
df['product'],
margins=True
)
print(ct_multi)
# product A B All
# gender region
# F East 0 1 1
# West 1 1 2
# M East 2 1 3
# West 0 1 1
# All 3 4 7crosstab() и pivot_table()
pd.crosstab() и pd.pivot_table() во многом пересекаются. crosstab оптимизирован для подсчёта частот и напрямую принимает входы, подобные массивам (а не DataFrame), поэтому для быстрых таблиц он немного компактнее. pivot_table работает с DataFrame и изначально поддерживает любую функцию агрегации. Для задач, связанных исключительно с подсчётом, выбирайте crosstab; для агрегирования числовых значений предпочитайте pivot_table.
# crosstab (more concise for counting)
print(pd.crosstab(df['gender'], df['product']))
# Equivalent pivot_table
print(pd.pivot_table(df, index='gender', columns='product',
aggfunc='size', fill_value=0))
# Both produce the same resultПодготовка к критерию хи-квадрат
Перекрёстная таблица является стандартным входом для критерия хи-квадрат на независимость, который проверяет, связаны ли статистически две категориальные переменные. Функция scipy.stats.chi2_contingency() напрямую принимает массив перекрёстной таблицы. Это один из самых распространённых способов использования crosstab в статистическом анализе данных: сначала вы вычисляете таблицу, а затем проверяете её в рамках одного процесса.
from scipy import stats
ct = pd.crosstab(df['gender'], df['product'])
# Convert to numpy array for scipy
chi2, p, dof, expected = stats.chi2_contingency(ct.values)
print(f'Chi2: {chi2:.2f}')
print(f'P-value: {p:.4f}')
print(f'Degrees of freedom: {dof}')
# p > 0.05 means no significant associationВизуализация перекрёстной таблицы в виде тепловой карты
Перекрёстные таблицы с большим количеством категорий трудно интерпретировать по исходным числам. Визуализация в виде тепловой карты с помощью sns.heatmap() сразу делает закономерности заметными: ячейки с высокой частотой отображаются яркими цветами. Передайте нормализованную версию, чтобы показать доли вместо исходных количеств, и используйте annot=True, чтобы отображать значения в каждой ячейке.
import seaborn as sns
import matplotlib.pyplot as plt
ct_norm = pd.crosstab(df['gender'], df['product'], normalize='index')
# sns.heatmap(ct_norm, annot=True, fmt='.0%', cmap='Blues')
# plt.title('Purchase Rate by Gender and Product')
# plt.tight_layout()
# plt.show()
print('Normalised crosstab ready for heatmap:')
print(ct_norm.round(2))Практический пример: анализ опроса
Полный процесс работы с перекрёстной таблицей выглядит так: загрузить данные опроса, вычислить таблицы частот между демографическими переменными и переменными ответов, нормализовать по строкам, чтобы получить показатели ответов, и выявить сильные закономерности. Это стандартный процесс анализа в маркетинговых исследованиях, A/B-тестировании и сегментации пользователей, который можно выполнить менее чем в 10 строках кода Pandas.
# Simulate a survey dataset
survey = pd.DataFrame({
'age_group': ['18-25', '26-35', '18-25', '36-45', '26-35', '36-45'],
'satisfaction': ['High', 'Low', 'High', 'Medium', 'High', 'Low']
})
ct = pd.crosstab(survey['age_group'], survey['satisfaction'],
margins=True, margins_name='Total')
print(ct)
rates = pd.crosstab(survey['age_group'], survey['satisfaction'],
normalize='index').round(2)
print(rates)Быстрая проверка
Проверьте своё понимание pd.crosstab для создания таблиц частот из этого урока.
Итоги урока
В этом уроке вы узнали, что pd.crosstab() вычисляет частоты комбинаций двух категориальных переменных; normalize преобразует количества в доли по строкам, столбцам или общую долю; margins=True добавляет итоги строк и столбцов; а результат crosstab напрямую совместим с критериями хи-квадрат и визуализацией в виде тепловой карты. Далее мы начнём работать с данными временных рядов, используя DatetimeIndex и диапазоны периодов.
Изучай Python с ИИ-репетитором — бесплатно
Пиши и запускай код прямо в браузере, получай мгновенную помощь от ИИ-репетитора 24/7 и продолжи учиться на сайте или в приложении.
- Курсы
- 30
- Уроки
- 120
Часто задаваемые вопросы
Урок «crosstab для таблиц частот» бесплатный?
Да — полный текст урока «crosstab для таблиц частот» бесплатно доступен здесь в веб-версии. Чтобы практиковать его интерактивно (встроенный редактор кода и ИИ-репетитор 24/7) и разблокировать остальной курс Pandas & NumPy Academy, подпишись на CoddyKit PRO. Курс Pandas & NumPy Academy содержит 4 уроков всего.
Чему я научусь в уроке «crosstab для таблиц частот»?
Вычисляйте перекрёстную таблицу частот или долей для двух категориальных столбцов с помощью pd.crosstab. Ты практикуешь Pandas & NumPy Academy с помощью реального кода, который запускаешь прямо в браузере, и ИИ-репетитор 24/7 отвечает на твои вопросы во время урока.
Нужен ли мне опыт, чтобы начать Pandas & NumPy Academy?
Предыдущий опыт не требуется. Pandas & NumPy Academy на CoddyKit структурирован для всех уровней — от новичков до продвинутых, поэтому ты можешь начать отсюда или с самого начала и учиться в своем темпе. Это урок 4 из 4.
Сколько времени занимает урок «crosstab для таблиц частот»?
Большинство уроков CoddyKit занимают около 5–10 минут. Каждый из них компактный и интерактивный, поэтому ты постоянно делаешь прогресс и продолжаешь с того же места в веб-версии и приложении.
Можно ли писать и запускать код в этом уроке Pandas & NumPy Academy?
Да. Каждый урок Pandas & NumPy Academy включает встроенный редактор кода, поэтому ты пишешь и запускаешь реальный код прямо в браузере и получаешь моментальную обратную связь от AI — локальная установка не требуется.
Все уроки этого курса
- pivot_table: перекрёстная таблица
- melt: из широкого формата в длинный
- stack и unstack с MultiIndex
- crosstab для таблиц частот