【Pandas分组聚合】进阶:透视表、交叉表(pivot_table() 、crosstab())

Pandas透视表、交叉表

  • 创建DataFrame结构
  • 透视表 pivot_table()
    • 单列聚合
    • 多列聚合
  • 交叉表 crosstab()
    • 计算分组频率
    • 两列分组后求第三列的统计指标

创建DataFrame结构

import pandas as pd
import numpy as np

df = 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)

【Pandas分组聚合】进阶:透视表、交叉表(pivot_table() 、crosstab())_第1张图片

透视表 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 函数参数说明

参数 说明
data 接收 DataFrame。表示创建表的数据。无默认
values 接收string 。用于指定想要聚合的数据字段名,默认使用全部数据。默认为 None
index 接收 string 或者 list。表示行分组键。默认为 None
columns 接收 string 或者 list。表示列分组键。默认为 None
aggfunc 接收 functions。表示聚合函数,默认为 mean
margins 接收 boolearn。表示汇总功能的开关,设为 True后结果集中会出现名为”ALL”的行和列,默认为True。
margins_name 接收string 。当margins打开后指定新行新列的名称,默认为“ALL”
fill_value 当存在缺失值时可以指定数值进行填充。默认为None(填充 NaN)
dropna 接收 boolearn。表示是否删除掉全为 NaN 的列,默认为 False。

单列聚合

例:查看各个班级的平均成绩

# groupby分组聚合
ret = df.groupby(by=['cls'])['score'].mean()
print('ret:\n', ret)
print('type:\n', type(ret))		# 最终结果是Series结构
"""
ret:
cls
A    81.500000
B    78.666667
Name: score, dtype: float64
type:

"""
# 使用透视表
ret = pd.pivot_table(
    data=df,  # 构建透视表的数据
    values=['score'],  # 关注的主题---需要统计指标的列
    index=['cls'],  # 指定结果的行索引
    aggfunc='mean',  # 对values中的列统计的指标
)
print('ret:\n', ret)
print('type:\n', type(ret))		# 最终结果是DataFrame结构
"""
ret:
         score
cls
A    81.500000
B    78.666667
type:
 
"""

多列聚合

例:查看各个班级、各个小组的成绩、身高的均值

ret = df.groupby(by=['cls', 'group'])[['score', 'height']].mean()
print('ret:\n', ret)
print('ret:\n', type(ret))
"""
ret:
                score      height     
cls group                             
A   1      98.333333  178.000000      
    2      64.666667  170.833333      
B   1      71.666667  187.000000      
    2      85.666667  159.166667      
ret:
 
 """
# 使用透视表
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:
                height      score
cls group
A   1      178.000000  98.333333
    2      170.833333  64.666667
B   1      187.000000  71.666667
    2      159.166667  85.666667
ret:
 
"""

例:查看满足在各个班级、各个小组的条件下, 成绩、身高的平均值

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:
       height               score
group      1      2  HELLO     1   2 HELLO
cls
A      180.0  175.0  180.0   100  87   100
B      190.0  160.0  190.0    89  89    89
HELLO  190.0  175.0  190.0   100  89   100
index:
 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'])
"""

出现以上结果的原因是:
【Pandas分组聚合】进阶:透视表、交叉表(pivot_table() 、crosstab())_第2张图片

交叉表 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  2
cls         
A      3  3 
B      3  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:
group          1          2
cls
A      98.333333  64.666667
B      71.666667  85.666667
"""

你可能感兴趣的:(Pandas,python,数据挖掘,数据分析)