Коротко
pivot_table(values, index, columns, aggfunc)— значения изindexстановятся строками, изcolumns— столбцами, в ячейках — итогaggfunc.- По умолчанию
aggfunc="mean"— для сумм укажите"sum"явно. fill_value=0заполняет пустые сочетания,margins=Trueдобавляет итоговые строку и столбец.indexиcolumnsмогут быть списками — получится MultiIndex.pd.crosstab(a, b)— таблица частот: сколько строк в каждом сочетании;normalize— доли.
Синтаксис
df.pivot_table(values=None, index=None, columns=None, aggfunc="mean",
fill_value=None, margins=False, margins_name="All", observed=True)
pd.crosstab(index, columns, values=None, aggfunc=None, normalize=False, margins=False)Параметры
ПараметрЧто делаетПо умолчанию
valuesстолбец (или список) с числами для итоговвсе числовыеindex / columnsчто станет строками / столбцами: столбец или списокNoneaggfuncфункция или список: "sum", "mean", "count", своя функция"mean"fill_valueчем заполнить отсутствующие сочетанияNonemarginsдобавить итоги по строкам и столбцамFalsenormalizeв crosstab: True / "all", "index", "columns" — доли вместо количествFalseПримеры
sales = pd.DataFrame({
"city": ["Омск", "Омск", "Тула", "Тула", "Омск", "Пермь", "Тула"],
"drink": ["латте", "чай", "латте", "латте", "латте", "чай", "чай"],
"month": ["янв", "янв", "янв", "фев", "фев", "фев", "фев"],
"cups": [30, 12, 18, 25, 20, 16, 9],
})sales.pivot_table(values="cups", index="city", columns="drink", aggfunc="sum")Вывод
drink латте чай city Омск 50.0 12.0 Пермь NaN 16.0 Тула 43.0 9.0
sales.pivot_table(values="cups", index="city", columns="drink",
aggfunc="sum", fill_value=0, margins=True, margins_name="Итого")Вывод
drink латте чай Итого city Омск 50 12 62 Пермь 0 16 16 Тула 43 9 52 Итого 93 37 130
sales.pivot_table(values="cups", index=["city", "month"], columns="drink", aggfunc="sum", fill_value=0)Вывод
drink латте чай
city month
Омск фев 20 0
янв 30 12
Пермь фев 0 16
Тула фев 25 9
янв 18 0sales.pivot_table(values="cups", index="city", aggfunc=["sum", "count"])Вывод
sum count
cups cups
city
Омск 62 3
Пермь 16 1
Тула 52 3pd.crosstab(sales["city"], sales["drink"]) # сколько строк в каждой пареВывод
drink латте чай city Омск 2 1 Пермь 0 1 Тула 2 1
pd.crosstab(sales["city"], sales["drink"], normalize="index").round(2) # доли по строкамВывод
drink латте чай city Омск 0.67 0.33 Пермь 0.00 1.00 Тула 0.67 0.33
Сводная таблица без агрегации (просто переложить значения) — pivot.
Подводные камни
Среднее вместо суммы
Если не передать aggfunc, в ячейках окажутся средние. Для одного значения на сочетание это незаметно, а при нескольких — итог неверный.
sales.pivot_table(values="cups", index="city", columns="drink") # без aggfunc — среднее!Вывод
drink латте чай city Омск 25.0 12.0 Пермь NaN 16.0 Тула 21.5 9.0