Это ошибка, связанная с поворотными столбцами, которые являются интервалами (см. GH25814 ) и будут исправлены для v0.25.Также просмотрите этот связанный вопрос, используя crosstab
: Кросс-таблица Pandas в столбцах CategoryoricalDType. Вызывает TypeError
. Ниже приведены некоторые параметры.Для агрегирования вам нужно будет использовать pivot_table
и преобразовать ваши категориальные столбцы в строку перед поворотом.
df2 = df.assign(cat1=df['cat1'].astype(str), cat2=df['cat2'].astype(str))
# to aggregate by taking the mean of col_a
df2.pivot_table(index='cat1', columns='cat2', values='col_a', aggfunc='mean')
Предостережение заключается в том, что вы теряете преимущество от того, что ваш индекс и столбцы являются интервалами.
Другим вариантом может быть поворот по категориальным кодам, а затем переназначение категорий:
df2 = df.assign(cat1=df['cat1'].cat.codes, cat2=df['cat2'].cat.codes)
pivot = df2.pivot_table(
index='cat1', columns='cat2', values='col_a', aggfunc='mean')
pivot.index = df['cat1'].cat.categories
pivot.columns = df['cat2'].cat.categories
Это назначение будет работать, поскольку pivot_table
сортирует интервалы заранее.
Образец минимального кода
import pandas as pd
import numpy as np
np.random.seed(0)
df = pd.DataFrame({
'cat1': np.random.choice(100, 10),
'cat2': np.random.choice(100, 10),
'col_a': np.random.randint(1, 50, 10)})
df['cat1'] = pd.cut(df['cat1'], bins=np.arange(0, 101, 10))
df['cat2'] = pd.cut(df['cat2'], bins=np.arange(0, 101, 10))
df
A B C
0 (40, 50] (60, 70] 18
1 (40, 50] (80, 90] 38
2 (60, 70] (80, 90] 26
3 (60, 70] (10, 20] 14
4 (60, 70] (50, 60] 9
5 (0, 10] (60, 70] 10
6 (80, 90] (30, 40] 21
7 (20, 30] (80, 90] 17
8 (30, 40] (40, 50] 6
9 (80, 90] (80, 90] 16
(df.assign(cat1=df['cat1'].astype(str), cat2=df['cat2'].astype(str))
.pivot_table(index='cat1', columns='cat2', values='col_a', aggfunc='mean'))
cat2 (10, 20] (30, 40] (40, 50] (50, 60] (60, 70] (80, 90]
cat1
(0, 10] NaN NaN NaN NaN 10.0 NaN
(20, 30] NaN NaN NaN NaN NaN 17.0
(30, 40] NaN NaN 6.0 NaN NaN NaN
(40, 50] NaN NaN NaN NaN 18.0 38.0
(60, 70] 14.0 NaN NaN 9.0 NaN 26.0
(80, 90] NaN 21.0 NaN NaN NaN 16.0