【Pandas分组聚合】进阶:透视表、交叉表(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)

在这里插入图片描述

透视表 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:
<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:
         score
cls
A    81.500000
B    78.666667
type:
 <class 'pandas.core.frame.DataFrame'>
"""

多列聚合

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

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:
 <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:
                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:
 <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:
       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'])
"""

出现以上结果的原因是:
在这里插入图片描述

交叉表 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
"""
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

胡桃の壶

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值