zoukankan      html  css  js  c++  java
  • Pandas学习总结——3. Pandas分组




    • SAC过程(split-apply-combine):其中split指基于某一些规则,将数据拆成若干组,apply是指对每一组独立地使用函数,combine指将每一组的结果组合成某一类数据结构。
    • apply过程:往往会遇到四类问题:
      • 整合(Aggregation)——即分组计算统计量(如求均值、求每组元素个数)
      • 变换(Transformation)——即分组对每个单元的数据进行操作(如元素标准化)
      • 过滤(Filtration)——即按照某些规则筛选出一些组(如选出组内某一指标小于50的组)
      • 综合问题——即前面提及的三种问题的混合

    1 groupby函数

    1.1 分组的依据

    • 根据某一列分组:grouped_single = df.groupby('School')
      • 可以通过get_group()取出某一个组。
    • 根据某几列分组:grouped_mul = df.groupby(['School','Class'])
    • 通过size()获取组容量
    • 通过ngroup()获取组数

    1.2 组的遍历

    for name,group in grouped_single:
        print(name)
        display(group.head(1))
    

    1.3 level参数(用于多级索引)和axis参数

    df.set_index(['Gender','School']).groupby(level=0,axis=0).get_group('M')
    

    1.4 groupby对象的特点

    • head()first():对分组对象使用head函数,返回的是每个组的前几行,而不是数据集前几行;first显示的是以分组为索引的每组的第一个分组信息
    grouped_single.head(2)
    
    grouped_single.first()
    
    • groupby的分组依据很自由,可以是列表和函数。(要与数据框长度相同)
    • 利用函数时,传入的对象就是索引;如果是多层索引,那么lambda表达式中的输入就是元组
    • 可以用[]选出groupby对象的某个或者某几个列。如:df.groupby(['Gender','School'])[['Math','Height']]
    • 利用cut()函数对数字进行分组。bins参数为分组列表。

    2 聚合、过滤和变换

    2.1 聚合(Aggregation)

    所谓聚合就是把一堆数,变成一个标量,因此mean/sum/size/count/std/var/sem/describe/first/last/nth/min/max都是聚合函数。

    • 聚合函数可以同时使用多个:
    group_m.agg(['sum','mean','std'])
    

    • 利用元组重命名:
    group_m.agg([('rename_sum','sum'),('rename_mean','mean')])
    

    • 指定哪些函数作用哪些列.
    grouped_mul.agg({'Math':['mean','max'],'Height':'var'})
    

    • 使用自定义函数:(通过agg可以容易地实现组内极差计算)
    grouped_single['Math'].agg(lambda x:x.max()-x.min())
    
    • 利用NamedAgg函数进行多个聚合(注意:不支持lambda函数,但是可以使用外置的def函数
    def R1(x):
        return x.max()-x.min()
    def R2(x):
        return x.max()-x.median()
    print(grouped_single['Math'].max())
    grouped_single['Math'].agg(min_score1=pd.NamedAgg(column='col1', aggfunc=R1),
                               max_score1=pd.NamedAgg(column='col2', aggfunc='max'),
                               range_score2=pd.NamedAgg(column='col3', aggfunc=R2)).head()
    

    • 带参数的聚合函数
    # 判断是否组内数学分数至少有一个值在50-52之间
    def f(s,low,high):
        return s.between(low,high).max()
    grouped_single['Math'].agg(f,50,52)
    
    # 如果需要使用多个函数,并且其中至少有一个带参数,则使用wrap技巧
    def f_test(s,low,high):
        return s.between(low,high).max()
    def agg_f(f_mul,name,*args,**kwargs):
        def wrapper(x):
            return f_mul(x,*args,**kwargs)
        wrapper.__name__ = name
        return wrapper
    new_f = agg_f(f_test,'at_least_one_in_50_52',50,52)
    grouped_single['Math'].agg([new_f,'mean']).head()
    

    2.2 过滤(Filteration)

    filter函数是用来筛选某些组的(务必记住结果是组的全体),因此传入的值应当是布尔标量

    grouped_single[['Math','Physics']].filter(lambda x:(x['Math']>32).all())
    # all()表示全部为Ture时进行过滤
    

    2.3 变换(Transformation)

    • transform函数中传入的对象是组内的列,并且返回值需要与列长完全一致
    • 如果返回了标量值,那么组内的所有元素会被广播为这个值。
    • 利用变换方法进行组内缺失值的均值填充
    df_nan = df[['Math','School']].copy().reset_index()
    df_nan.loc[np.random.randint(0,df.shape[0],25),['Math']]=np.nan # 0-35的随机数,25个
    
    df_nan.groupby('School').transform(lambda x: x.fillna(x.mean())).join(df.reset_index()['School'])
    

    3 apply函数

    在第一章里面介绍过,apply函数使用相当灵活,因此其应用也是最为广泛。

    3.1 apply函数的灵活性

    apply函数的灵活性体现在以下几个方面:

    • 标量返回值;
    • 列表返回值;
    • 数据框返回值
    # 返回标量
    df[['School','Math','Height']].groupby('School').apply(lambda x:x.max())
    
    # 返回列表
    df[['School','Math','Height']].groupby('School').apply(lambda x:x-x.min())
    
    # 返回数据框
    df[['School','Math','Height']].groupby('School')
        .apply(lambda x:pd.DataFrame({'col1':x['Math']-x['Math'].max(),
                                      'col2':x['Math']-x['Math'].min(),
                                      'col3':x['Height']-x['Height'].max(),
                                      'col4':x['Height']-x['Height'].min()}))
    

    3.2 应用apply同时统计多个指标

    可以借助OrderedDict工具进行快捷的统计。

    from collections import OrderedDict
    def f(df):
        data = OrderedDict()
        data['M_sum'] = df['Math'].sum()
        data['W_var'] = df['Weight'].var()
        data['H_mean'] = df['Height'].mean()
        return pd.Series(data)
    grouped_single.apply(f)
    

  • 相关阅读:
    与生命晒跑
    关于你有一条未读短信的静态单页
    【微收藏】来自Twitter的自动文字补齐jQuery插件
    chrome 插件个人使用推介
    vscode中检测代码中的空白行并去除的方法
    FTP文件乱码导致的无法删除
    git操作遇到的几个问题
    一个srand、rand结果相同的问题
    【verilog】单周期MIPS CPU设计
    【verilog】多周期MIPS CPU设计
  • 原文地址:https://www.cnblogs.com/KaifengGuan/p/12783524.html
Copyright © 2011-2022 走看看