本文的前半部分:python 数据聚合与分组运算(part 1)
4. 透视表和交叉表
透视表(pivot table)是各种电子表格程序和其他数据分析软件中一种常见的数据汇总工具。它根据一个或多个键对数据进行聚合,并根据行和列上的分组键将数据分配到各个矩形区域中。在Python和pandas中,可以通过本章所介绍的groupby功能以及(能够利用层次化索引的)重塑运算制作透视表。DataFrame有一个pivot_table方法,此外还有一个顶级的pandas.pivot_table函数。除能为groupby提供便利之外,pivot_table还可以添加分项小计,也叫做margins。
回到小费数据集,假设我想要根据day和smoker计算分组平均数(pivot_table的默认聚合类型),并将day和smoker放到行上:
tips.pivot_table(index=['day', 'smoker'])
如果pivot_table不带统计参数的话,默认计算平均值。
可以用groupby直接来做。现在,假设我们只想聚合tip_pct和size,而且想根据time进行分组。我将smoker放到列上,把day放到行上:
tips.pivot_table(['tip_pct', 'size'], index=['time', 'day'],
columns='smoker')
透视表的参数可以这样记忆:需要统计哪些指标,直接给出;需要在行上分组,用index给出;需要在列上分组,用columns给出。
还可以对这个表作进一步的处理,传入margins=True添加分项小计。这将会添加标签为All的行和列,其值对应于单个等级中所有数据的分组统计:
tips.pivot_table(['tip_pct', 'size'], index=['time', 'day'],
columns='smoker', margins=True)
这里,All值为平均数:不单独考虑烟民与非烟民(All列),不单独考虑行分组两个级别中的任何单项(All行)。
要使用其他的聚合函数,将其传给 aggfunc 即可。例如,使用count或len可以得到有关分组大小的交叉表(计数或频率):
tips.pivot_table('tip_pct', index=['time', 'smoker'], columns='day',
aggfunc=len, margins=True)
如果结果表中存在空的组合(也就是NA),你可能会希望设置一个fill_value:
tips.pivot_table('tip_pct', index=['time', 'size', 'smoker'],
columns='day', aggfunc='mean', fill_value=0)
pivot_table的参数说明请参见表10-2。
表10-2 pivot_table的选项
交叉表:crosstab
交叉表(cross-tabulation,简称crosstab)是一种用于计算分组频率的特殊透视表。看下面的例子:
pd.crosstab(data.Nationality, data.Handedness, margins=True)
crosstab的参数记忆方法:直接把要做交叉统计的行、列名称写出来就行。
crosstab的前两个参数可以是数组或Series,或是数组列表。就像小费数据:
pd.crosstab([tips.time, tips.day], tips.smoker, margins=True)
10.5 总结
掌握pandas数据分组工具既有助于数据清理,也有助于建模或统计分析工作。
参考:
《利用Python进行数据分析·第2版》