Pandas透视表、交叉表
创建DataFrame结构透视表 pivot_table()单列聚合多列聚合交叉表 crosstab()计算分组频率两列分组后求第三列的统计指标创建DataFrame结构
import pandas as pdimport numpy as npdf = pd.DataFrame(data={'name': ['z_s', 'l_s', 'w_w', 'z_l', 'y_s', 'j_j', 'l_b', 'z_f', 'hs_q', 'lbl_k', 'qy_n', 'mg_n'],'score': [100, 97, 98, 89, 67, 59, 29, 87, 78, 89, 88, 80],'group': [1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2],'cls': ['A', 'A', 'A', 'B', 'B', 'B', 'A', 'A', 'A', 'B', 'B', 'B'],'height': [178.0, 180.0, 176.0, 182.0, 189.0, 190.0, 172.5, 175.0, 165.0, 160.0, 158.5, 159.0]},index=['stu_' + str(i) for i in np.arange(1, 13, 1)])print('df:\n', df)
透视表 pivot_table()
透视表是一种可以对数据动态排布并且分类汇总的表格格式,相比groupby,灵活性更高,操作性更强。
pands.pivot_table(data,values=None,index=None,columns=None,aggfunc=‘mean’,fill_value=None,margins=False,dropna=True,margins_name=‘All’)
pivot_table 函数参数说明
单列聚合
例:查看各个班级的平均成绩
# groupby分组聚合ret = df.groupby(by=['cls'])['score'].mean()print('ret:\n', ret)print('type:\n', type(ret))# 最终结果是Series结构"""ret:clsA 81.500000B 78.666667Name: score, dtype: float64type:<class 'pandas.core.series.Series'>"""# 使用透视表ret = pd.pivot_table(data=df, # 构建透视表的数据values=['score'], # 关注的主题---需要统计指标的列index=['cls'], # 指定结果的行索引aggfunc='mean', # 对values中的列统计的指标)print('ret:\n', ret)print('type:\n', type(ret))# 最终结果是DataFrame结构"""ret:scoreclsA 81.500000B 78.666667type:<class 'pandas.core.frame.DataFrame'>"""
多列聚合
例:查看各个班级、各个小组的成绩、身高的均值
ret = df.groupby(by=['cls', 'group'])[['score', 'height']].mean()print('ret:\n', ret)print('ret:\n', type(ret))"""ret:scoreheightcls group A 198.333333 178.000000264.666667 170.833333B 171.666667 187.000000285.666667 159.166667ret:<class 'pandas.core.frame.DataFrame'>"""# 使用透视表ret = pd.pivot_table(data=df, # 构建透视表的数据values=['score', 'height'], # 关注的主题---需要统计指标的列index=['cls', 'group'], # 指定结果的行索引aggfunc='mean', # 对values中的列统计的指标)print('ret:\n', ret)print('ret:\n', type(ret))"""ret:heightscorecls groupA 1178.000000 98.3333332170.833333 64.666667B 1187.000000 71.6666672159.166667 85.666667ret:<class 'pandas.core.frame.DataFrame'>"""
例:查看满足在各个班级、各个小组的条件下, 成绩、身高的平均值
ret = pd.pivot_table(data=df,values=['score', 'height'],index=['cls'],columns=['group'], # 指定结果的列索引aggfunc='max',margins=True, # 打开margins开关-->给生成结果多出来几列,再结果统计aggfunc的指标margins_name='HELLO', # 开关的名称-->多出来的几列、几行的行列名称)print('ret:\n', ret)print('index:\n', ret.index)print('columns:\n', ret.columns) # MultiIndex 多重列索引"""ret:heightscoregroup12 HELLO1 2 HELLOclsA180.0 175.0 180.0 100 87 100B190.0 160.0 190.0 89 89 89HELLO 190.0 175.0 190.0 100 89 100index:Index(['A', 'B', 'HELLO'], dtype='object', name='cls')columns:MultiIndex([('height', 1),('height', 2),('height', 'HELLO'),( 'score', 1),( 'score', 2),( 'score', 'HELLO')],names=[None, 'group'])"""
出现以上结果的原因是:
交叉表 crosstab()
交叉表是一种特殊的透视表,主要用于计算分组频率。
由于交叉表是透视表的一种,其参数基本保持一致,不同之处在于 crosstab 函数中的index,columns,values 填入的都是对应的从 Dataframe 中取出的某一列。
计算分组频率
例:统计分组频率,在满足以index为行分组,以columns为列分组时,数据的数量
# 生成交叉表的时候,index和 columns必须同时存在,且必须要有!ret = pd.crosstab(index=df['cls'], # 指定的是结果的行索引columns=df['group'], # 指定结果的列索引)print('ret:\n', ret)"""ret:group 1 2cls A3 3 B3 3 """
两列分组后求第三列的统计指标
例:求在满足各个班级、各个小组的条件下,成绩的均值
ret = pd.crosstab(index=df['cls'],columns=df['group'],values=df['score'], # 注意:可以指定values --但是vlues只能是某一列数据aggfunc=np.mean, # --values这个参数出现的时候,必须要指定aggfunc)print('ret:\n', ret)"""ret:group12clsA98.333333 64.666667B71.666667 85.666667"""