pandas crosstab(): таблицы сопряжённости, частоты и доли

pd.crosstab строит таблицу сопряжённости — по умолчанию считает, сколько раз встретилась каждая комбинация значений двух (и более) признаков. Аналитику это быстрый способ увидеть распределение «канал × устройство» без ручного groupby. Умеет доли (normalize), итоги (margins) и агрегацию по третьей колонке (values + aggfunc). Под капотом это удобная обёртка над pivot_table.

Синтаксис

pd.crosstab(index, columns, values=None, aggfunc=None, margins=False, normalize=False)

Примеры использования

Пример 1: Частоты: канал × устройство

import pandas as pd
df = pd.DataFrame({
    'channel': ['seo','ads','seo','seo','ads'],
    'device': ['mobile','desktop','desktop','mobile','mobile']
})
pd.crosstab(df['channel'], df['device'])

Результат:

device   desktop  mobile
channel
ads            1       1
seo            1       2

Пример 2: Доли и итоги: normalize + margins

pd.crosstab(df['channel'], df['device'],
            margins=True, normalize=True)

Результат:

device   desktop  mobile   All
channel
ads          0.2     0.2   0.4
seo          0.2     0.4   0.6
All          0.4     0.6   1.0

Пример 3: Агрегация суммы через values + aggfunc

df2 = pd.DataFrame({
    'channel': ['seo','ads','seo','ads'],
    'device': ['mobile','mobile','desktop','desktop'],
    'amount': [100, 250, 140, 300]
})
pd.crosstab(df2['channel'], df2['device'],
            values=df2['amount'], aggfunc='sum')

Результат:

device   desktop  mobile
channel
ads          300     250
seo          140     100
Порешать Python-задачи в тренажёре →

Типичная ошибка

crosstab принимает на вход сами Series/массивы, а не имена колонок — частая ошибка передать строку 'channel' вместо df['channel']. При values= обязательно указывать aggfunc, иначе будет ошибка. normalize даёт float-доли, из-за чего теряются целочисленные счётчики.

Где спрашивают на собеседовании

Просят на собесе для быстрой таблицы сопряжённости двух признаков (частоты, доли), рядом с вопросами про pivot_table и groupby.

FAQ: частые вопросы про crosstab

Чем crosstab отличается от pivot_table?

crosstab по умолчанию считает частоты (count) и принимает на вход сами Series или массивы, а не имена колонок. pivot_table работает с колонками DataFrame и по умолчанию усредняет. По сути crosstab — это специализированная обёртка над pivot_table для таблиц сопряжённости.

Как получить доли вместо количеств?

Параметр normalize: True — доля от общей суммы, 'index' — по строкам, 'columns' — по столбцам. Вместе с margins=True добавится строка и столбец 'All' с итогами, что удобно для быстрой проверки распределения.

Можно ли считать не количество, а сумму?

Да, передайте values= и aggfunc=, например values=df['amount'], aggfunc='sum'. Тогда crosstab превращается в обычную сводную с агрегацией по указанной функции вместо простого подсчёта строк.

Задачи в тренажёре по теме

Вопросы с собеседований по теме

Смежные темы Python

Pandas groupby · Pandas: основы

Другие функции pandas

groupby · merge · pivot_table · apply · value_counts · drop_duplicates

Открыть Python-тренажёр (556 задач) →