Pandas透视表和交叉表

透视表
透视表(pivot table)是各种电子表格程序和其他数据分析软件中一种常见的数据汇总工具。它根据一个或多个键对数据进行聚合,并根据行和列上得分组建将数据分配到各个矩形区域中。在Python和pandas中,可以通过本章所介绍的groupby功能以及(能够利用层次化索引的)重塑运算制作透视表。DataFrame有一个pivot_table方法,此外还有一个*的pandas.pivot_table函数。除了能为groupby提供便利之外,pivot_table还可以添加分项小计(也叫margins)。

首先导入tips数据集 ,添加一项tips[‘tip_pct’] = tips[‘tip’] / tips[‘total_bill’]
Pandas透视表和交叉表
回到如上图所示的小费数据集,假设我想要根据sex和smoker计算分组平均数(pivot_table的默认聚合类型),并将sex和smoker放到行上:

方法一:使用groupby

tips.groupby([‘sex’, ‘smoker’]).mean()

方法二:使用pivot_table

tips.pivot_table(row=[‘sex’, ‘smoker’])

Pandas透视表和交叉表
结果是一样的
现在假设我们只想聚合tip_pct和size,而且想根据day进行分组。我将smoker放到列上,把day放到行上:
tips.pivot_table(values=[‘tip_pct’, ‘size’], index=[‘sex’, ‘day’], columns=‘smoker’)
Pandas透视表和交叉表
可以看到,pivot_table()函数给我们提供了很多参数,用来选择用那些数据创建透视表,以及调整创建透视表之后的行和列。
还可以对这个表作进一步处理,传入margins=True添加加分小计。这将会添加标签为ALL的行和列,其值对应于单个等级中所有数据的分组统计。在下面这个例子中,ALL值为平均数:不单独考虑烟民与非烟民(ALL列),不单独考虑行分组两个级别中的任何单项(ALL行)。换句话说:就是下面的ALL行和右边的ALL列只统计对应的列和行。
tips.pivot_table(values=[‘tip_pct’, ‘size’], index=[‘sex’, ‘day’], columns=‘smoker’, margins=True)
Pandas透视表和交叉表
交叉表:crosstab
交叉表(cross-tabulation, 简称crosstab)是一种用于计算分组频率的特殊透视表。下面这个范例数据很典型,取自交叉表的Wikipedia页:

data = pd.DataFrame({‘Sample’: range(1, 11), ‘Gender’: [‘Female’, ‘Male’, ‘Female’, ‘Male’, ‘Male’, ‘Male’, ‘Female’, ‘Female’, ‘Male’, ‘Female’],
‘Handedness’: [‘Right-handed’, ‘Left-handed’, ‘Right-handed’, ‘Right-handed’, ‘Left-handed’, ‘Right-handed’, ‘Right-handed’, ‘Left-handed’, ‘Right-handed’, ‘Right-handed’]})
Pandas透视表和交叉表

方法一:用pivot_table

data.pivot_table(index=[‘Gender’], columns=‘Handedness’, aggfunc=len, margins=True)

方法二:用crosstab

pd.crosstab(data.Gender, data.Handedness, margins=True)
Pandas透视表和交叉表
Pandas透视表和交叉表
可以看到,crosstab()的前两个参数可以是数组、Series或数组列表。再比如对小费数据集:

pd.crosstab([tips.time, tips.day], tips.smoker, margins=True)
Pandas透视表和交叉表
总结
透视表pivot_table()是一种进行分组统计的函数,参数aggfunc决定统计类型;
交叉表crosstab()是一种特殊的pivot_table(),专用于计算分组频率。