Функция Pandas pd.crosstab()
pd.crosstab()используется в библиотеке Pandas длявычисления перекрестной табуляциифункции. Она может вычислять частоту или агрегированную статистику двух или более переменных и создавать таблицу, подобную сводной таблице Excel.
Перекрестная табуляция — очень полезный инструмент в статистическом анализе, часто используемый для анализа связи между двумя или более категориальными переменными, например для подсчета числа сотрудников мужского и женского пола в разных отделах.
Значение слова: crosstab— это сокращение от «перекрестной табуляции», статистической таблицы, отображающей совместное распределение двух или более переменных.
Базовый синтаксис и параметры
pd.crosstab()— это функция верхнего уровня библиотеки Pandas, используемая для вычисления перекрестных табуляций.
Формат синтаксиса
pd.crosstab(index, columns, values=None, aggfunc=None, margins=False, margins_name='All', dropna=True, normalize=False)
Описание параметра
- Параметр:
index- Тип: array-like, Series или list.
- Описание: Данные, используемые в качестве индекса строк. Может быть одним столбцом или несколькими столбцами (list).
- Параметр:
columns- Тип: array-like, Series или list.
- Описание: Данные, используемые в качестве индекса столбцов. Может быть одним столбцом или несколькими столбцами (list).
- Параметр:
values- Тип: array-like или None.
- Описание: Значения для агрегирования. Если указано, это должно использоваться вместе с
aggfuncпараметра.
- Параметр:
aggfunc- Тип: функция или строка.
- Описание: Функция агрегации (например, 'sum', 'mean', 'count' и т. д.). Когда указана
valuesеё необходимо использовать.
- Параметр:
margins- Тип: логическое значение.
- Описание: Если
True, добавьте итоги по строкам и столбцам. По умолчанию —False。
- Параметр:
normalize- Тип: логическое значение или 'all', 'index', 'columns'.
- Описание: Если
True, разделите значения на общую сумму, чтобы получить пропорции (0-1). Также можно указать 'index' или 'columns', чтобы нормализовать по строкам или столбцам.
Описание функций
- Возвращаемое значение: Возвращает DataFrame, представляющий взаимосвязь между двумя или более переменными.
- Эффект: Создаёт таблицу, в которой строки и столбцы представляют различные категориальные переменные, а ячейки отображают соответствующую частоту или агрегированное значение.
Примеры
Давайте досконально освоим через серию примеров от простого к сложномуpd.crosstab()использование.
Пример 1: Базовое использование — перекрёстная табуляция двух категориальных переменных
Примеры
# 1. Создать данные сотрудников
employees = pd.DataFrame({
'department': ['Продажи', 'Продажи', 'Продажи', 'Инженерия', 'Инженерия', 'HR', 'HR', 'Продажи', 'Инженерия', 'HR'],
'gender': ['Мужской', 'Женский', 'Женский', 'Мужской', 'Мужской', 'Женский', 'Мужской', 'Женский', 'Женский', 'Мужской']
})
print("=== Данные сотрудников ===")
print(employees)
# 2. Вычислить кросс-табуляцию отдела и пола (частоту)
result = pd.crosstab(employees['department'], employees['gender'])
print("n=== pd.crosstab() Кросстабуляция отделов и пола ===")
print(result)
Ожидаемый вывод:
=== 员工数据 === department gender 0 Sales Male 1 Sales Female 2 Sales Female 3 Engineering Male 4 Engineering Male 5 HR Female 6 HR Male 7 Sales Female 8 Engineering Female 9 HR Male === pd.crosstab() 部门与性别交叉表 === gender Female Male department Engineering 1 2 HR 1 2 Sales 3 1
Пояснение к коду:
- В результирующей таблице отображается количество сотрудников мужского и женского пола в каждом отделе.
Пример 2: Добавление итогов по строкам/столбцам и нормализация
Используйтеmarginsпараметр для добавления итогов,normalizeпараметр для просмотра распределения долей.
Примеры
# Используйте приведённые выше данные о сотрудниках
employees = pd.DataFrame({
'department': ['Продажи', 'Продажи', 'Продажи', 'Инженерия', 'Инженерия', 'HR', 'HR', 'Продажи', 'Инженерия', 'HR'],
'gender': ['Мужской', 'Женский', 'Женский', 'Мужской', 'Мужской', 'Женский', 'Мужской', 'Женский', 'Женский', 'Мужской']
})
# 1. Добавьте итоги по строкам и столбцам
result_margins = pd.crosstab(employees['department'], employees['gender'], margins=True)
print("=== Добавление итогов (margins=True) ===")
print(result_margins)
# 2. Нормализация - преобразование в пропорции
print("n=== Общая нормализация (normalize=True) ===")
result_norm = pd.crosstab(employees['department'], employees['gender'], normalize=True)
print(result_norm.round(3))
# 3. Нормализация по строкам (сумма каждой строки равна 1)
print("n=== Нормализация по строкам (normalize='index') ===")
result_norm_index = pd.crosstab(employees['department'], employees['gender'], normalize='index')
print(result_norm_index.round(3))
# 4. Нормализация по столбцам (сумма каждого столбца равна 1)
print("n=== Нормализация по столбцам (normalize='columns') ===")
result_norm_col = pd.crosstab(employees['department'], employees['gender'], normalize='columns')
print(result_norm_col.round(3))
Ожидаемый вывод:
=== 添加合计 (margins=True) === gender Female Male All department Engineering 1 2 3 HR 1 2 3 Sales 3 1 4 All 5 5 10 === 整体归一化 (normalize=True) === gender Female Male department Engineering 0.1 0.2 HR 0.1 0.2 Sales 0.3 0.1 === 按行归一化 (normalize='index') === gender Female Male department Engineering 0.333 0.667 HR 0.333 0.667 Sales 0.75 0.25 === 按列归一化 (normalize='columns') === gender Female Male department Engineering 0.2 0.4 HR 0.2 0.4 Sales 0.6 0.2
Пояснение к коду:
- Нормализация облегчает анализ пропорциональных соотношений и понимание относительного распределения пола в каждом отделе.
- Нормализация по строкам показывает процентное распределение пола в каждом отделе.
- Нормализация по столбцам показывает долю распределения каждого пола по отделам.
Пример 3: Несколько переменных и функции агрегирования
Вы можете использовать несколько переменных строк/столбцов и применять функции агрегирования для вычисления статистических значений.
Примеры
import numpy as np
# 1. Создание данных о продажах
sales = pd.DataFrame({
'region': ['North', 'North', 'South', 'South', 'East', 'East', 'West', 'West', 'North', 'South'],
'product': ['A', 'B', 'A', 'B', 'A', 'B', 'A', 'B', 'B', 'A'],
'quarter': ['Q1', 'Q1', 'Q1', 'Q1', 'Q2', 'Q2', 'Q2', 'Q2', 'Q2', 'Q2'],
'sales': [100, 150, 200, 180, 120, 160, 190, 170, 140, 210]
})
print("=== Данные о продажах ===")
print(sales)
# 2. Использование нескольких переменных строк
print("n=== Кросс-табуляция региона и продукта (частота) ===")
result_multi = pd.crosstab([sales['region'], sales['product']], sales['quarter'])
print(result_multi)
# 3. Используйте values и aggfunc для расчёта суммы продаж
print("n=== Общая сумма продаж по регионам и кварталам ===")
result_sum = pd.crosstab(sales['region'], sales['quarter'], values=sales['sales'], aggfunc='sum')
print(result_sum)
# 4. Вычислите среднюю сумму продаж
print("n=== Средняя сумма продаж по регионам и кварталам ===")
result_mean = pd.crosstab(sales['region'], sales['quarter'], values=sales['sales'], aggfunc='mean')
print(result_mean.round(1))
Ожидаемый вывод:
=== 销售数据 ===
region product quarter sales
0 North A Q1 100
1 North B Q1 150
2 South A Q1 200
3 South B Q1 180
4 East A Q2 120
5 East B Q2 160
6 West A Q2 190
7 West B Q2 170
8 North B Q2 140
9 South A Q2 210
=== 区域和产品的交叉表(频次)===
quarter Q1 Q2
region product
East A 0 1
B 0 1
North A 1 0
B 1 1
South A 1 1
B 1 0
West A 0 1
B 0 1
=== 区域和季度的销售额合计 ===
quarter Q1 Q2
region
East NaN 280
North 250 140
South 380 210
West NaN 360
=== 区域和季度的平均销售额 ===
quarter Q1 Q2
region
East NaN 140.0
North 125.0 140.0
South 190.0 210.0
West NaN 180.0
Пояснение к коду:
- Использование нескольких переменных-строк (в виде списка) позволяет создать кросс-табуляцию с многоуровневой индексацией.
- Каждая ячейка отображает количество вхождений определённой комбинации регион-продукт в конкретном квартале.
- Использование параметров values и aggfunc позволяет вычислять агрегаты фактических числовых значений (сумма, среднее и т. д.).
Пример 4: Обработка пропущенных значений
dropnaПараметр управляет тем, включаются ли пропущенные категории.
Примеры
import numpy as np
# 1. Данные, содержащие пропущенные значения
data = pd.DataFrame({
'A': ['a', 'a', 'b', np.nan, 'a', 'b'],
'B': ['x', 'y', 'x', 'x', np.nan, 'y']
})
print("=== Данные с пропущенными значениями ===")
print(data)
# 2. По умолчанию удаляются комбинации, содержащие пропущенные значения
result_drop = pd.crosstab(data['A'], data['B'])
print("n=== Удаление пропущенных значений по умолчанию (dropna=True) ===")
print(result_drop)
# 3. Включить пропущенные категории
result_keep = pd.crosstab(data['A'], data['B'], dropna=False)
print("n=== Включить пропущенные категории (dropna=False) ===")
print(result_keep)
Ожидаемый вывод:
=== 包含缺失值的数据 ===
A B
0 a x
1 a y
2 b x
3 NaN x
4 a NaN
5 b y
=== 默认移除缺失值 (dropna=True) ===
B x y
A
a 1 1
b 1 1
=== 包含缺失值 (dropna=False) ===
B x y NaN
A
a 1 1 1
b 1 1 0
NaN 1 0 0
Пояснение к коду:
- По умолчанию
dropna=Trueудалит строки и столбцы, содержащие пропущенные значения, отображая только валидные данные. - Используйте
dropna=Falseдля просмотра частоты комбинаций, содержащих пропущенные значения.
Другие расширенияСовет:
pd.crosstab()подходит для анализа взаимосвязей между категориальными переменными. Если вам нужна более сложная сводка данных (например, расчет нескольких агрегационных показателей), используйтеpd.pivot_table()функцию.
Pandas: общие функции