• Pandas知识点-详解聚合函数agg


    Pandas知识点-详解聚合函数agg

    Pandas提供了多个聚合函数,聚合函数可以快速、简洁地将多个函数的执行结果聚合到一起。
    本文介绍的聚合函数为DataFrame.aggregate(),别名DataFrame.agg(),aggregate()和agg()是同一个函数,仅名字不同。
    agg()参数和用法介绍
    agg(self, func=None, axis=0, *args, **kwargs):

    • func: 用于聚合数据的函数,如max()、mean()、count()等,函数必须满足传入一个DataFrame能正常使用,或传递到DataFrame.apply()中能正常使用。
      func参数可以接收函数的名字、函数名的字符串、函数组成的列表、行/列标签和函数组成的字典。
    • axis: 设置按列还是按行聚合。设置为0或index,表示对每列应用聚合函数,设置为1或columns,表示对每行应用聚合函数。
    • *args: 传递给函数func的位置参数。
    • **kwargs: 传递给函数func的关键字参数。

    返回的数据分为三种:scalar(标量)、Series或DataFrame。

    • scalar: 当Series.agg()聚合单个函数时返回标量。
    • Series: 当DataFrame.agg()聚合单个函数时,或Series.agg()聚合多个函数时返回Series。
    • DataFrame: 当DataFrame.agg()聚合多个函数时返回DataFrame。

    传入单个参数

    # coding=utf-8
    import pandas as pd
    import numpy as np
    
    
    df = pd.DataFrame(
        {'Col-1': [1, 3, 5], 'Col-2': [2, 4, 6],
         'Col-3': [9, 8, 7], 'Col-4': [3, 6, 9]},
        index=['A', 'B', 'C'])
    print(df)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
       Col-1  Col-2  Col-3  Col-4
    A      1      2      9      3
    B      3      4      8      6
    C      5      6      7      9
    
    • 1
    • 2
    • 3
    • 4
    res1 = df.agg(np.mean)
    print('-' * 30, '\n', res1, sep='')
    res2 = df.mean()  # 调用Python内置函数
    print('-' * 30, '\n', res2, sep='')
    res3 = df['Col-1'].agg(np.mean)
    print('-' * 30, '\n', res3, sep='')
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    ------------------------------
    Col-1    3.0
    Col-2    4.0
    Col-3    8.0
    Col-4    6.0
    dtype: float64
    ------------------------------
    Col-1    3.0
    Col-2    4.0
    Col-3    8.0
    Col-4    6.0
    dtype: float64
    ------------------------------
    3.0
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    DataFrame应用单个函数时,agg()的结果与用apply()的结果等效,用DataFrame调用Python的内置函数也可以实现相同效果。
    apply()详解参考:Pandas知识点-详解行列级批处理函数apply
    Series对象在agg()中传入单个函数,聚合结果为标量值,也就是单个数据。
    多种方式传入函数func

    # 用列表的方式传入
    res4 = df.agg([np.mean, np.max, np.sum])
    print('-' * 30, '\n', res4, sep='')
    # 用字典的方式传入
    res5 = df.agg({'Col-1': [sum, max], 'Col-2': [sum, min], 'Col-3': [max, min]})
    print('-' * 30, '\n', res5, sep='')
    # 函数名用字符串的方式传入
    res6 = df.agg({'Col-1': ['sum', 'max'], 'Col-2': ['sum', 'min'], 'Col-3': ['max', 'min']})
    print('-' * 30, '\n', res6, sep='')
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    ------------------------------
          Col-1  Col-2  Col-3  Col-4
    mean    3.0    4.0    8.0    6.0
    amax    5.0    6.0    9.0    9.0
    sum     9.0   12.0   24.0   18.0
    ------------------------------
         Col-1  Col-2  Col-3
    sum    9.0   12.0    NaN
    max    5.0    NaN    9.0
    min    NaN    2.0    7.0
    ------------------------------
         Col-1  Col-2  Col-3
    sum    9.0   12.0    NaN
    max    5.0    NaN    9.0
    min    NaN    2.0    7.0
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    在agg()中,可以用列表的方式传入多个函数,会将这些函数在每一列的执行结果聚合到一个DataFrame中,结果DataFrame中的索引为对应的函数名。
    也可以用字典的方式按列/行指定聚合函数,会将指定列/行与对应函数的执行结果聚合到一个DataFrame中,列/行和函数没有对应关系的位置填充空值。
    在上面的情况中,函数名都可以换成用字符串的方式传入,结果一样。

    # 用元组的方式按列/行传入函数
    res7 = df.agg(X=('Col-1', 'sum'), Y=('Col-2', 'max'), Z=('Col-3', 'min'),)
    print('-' * 30, '\n', res7, sep='')
    res8 = df.agg(X=('Col-1', 'sum'), Y=('Col-2', 'max'), Zmin=('Col-3', 'min'), Zmax=('Col-3', 'max'))
    print('-' * 30, '\n', res8, sep='')
    
    • 1
    • 2
    • 3
    • 4
    • 5
    ------------------------------
       Col-1  Col-2  Col-3
    X    9.0    NaN    NaN
    Y    NaN    6.0    NaN
    Z    NaN    NaN    7.0
    ------------------------------
          Col-1  Col-2  Col-3
    X       9.0    NaN    NaN
    Y       NaN    6.0    NaN
    Zmin    NaN    NaN    7.0
    Zmax    NaN    NaN    9.0
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    agg()还支持将不同的列/行和函数组合成元组,赋值给一个自定义的索引名,聚合结果DataFrame的索引按自定义的值重命名。
    用这种方式传入函数时,元组中只能有两个元素:列/行名和一个函数,不能同时传入多个函数,如果要对同一列/行执行多个函数,需要用多个元组多次赋值。
    传入自定义函数和匿名函数

    def fake_mean(s):
        return (s.max()+s.min())/2
    
    
    res9 = df.agg([fake_mean, lambda x: x.mean()])
    print('-' * 40, '\n', res9, sep='')
    res10 = df.agg([fake_mean, lambda x: x.max(), lambda x: x.min()])
    print('-' * 40, '\n', res10, sep='')
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    ----------------------------------------
               Col-1  Col-2  Col-3  Col-4
    fake_mean    3.0    4.0    8.0    6.0
         3.0    4.0    8.0    6.0
    ----------------------------------------
               Col-1  Col-2  Col-3  Col-4
    fake_mean    3.0    4.0    8.0    6.0
         5.0    6.0    9.0    9.0
         1.0    2.0    7.0    3.0
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    传入自定义函数和匿名函数时,聚合结果中对应的索引也是显示函数名字,匿名函数显示,有多个匿名函数时,同时显示
    这里需要注意,只有匿名函数可以传入重复的函数,自定义函数和内置函数等不能重复,会报错SpecificationError: Function names must be unique if there is no new column names assigned。
    自定义实现describe函数的效果

    print(df.describe())
    
    • 1
           Col-1  Col-2  Col-3  Col-4
    count    3.0    3.0    3.0    3.0
    mean     3.0    4.0    8.0    6.0
    std      2.0    2.0    1.0    3.0
    min      1.0    2.0    7.0    3.0
    25%      2.0    3.0    7.5    4.5
    50%      3.0    4.0    8.0    6.0
    75%      4.0    5.0    8.5    7.5
    max      5.0    6.0    9.0    9.0
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    describe()函数包含了数值个数、均值、标准差、最小值、1/4分位数、中位数、3/4分位数、最大值。

    from functools import partial
    
    # 20%分为数
    per_20 = partial(pd.Series.quantile, q=0.2)
    per_20.__name__ = '20%'
    # 80%分为数
    per_80 = partial(pd.Series.quantile, q=0.8)
    per_80.__name__ = '80%'
    res11 = df.agg([np.min, per_20, np.median, per_80, np.max])
    print('-' * 40, '\n', res11, sep='')
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
            Col-1  Col-2  Col-3  Col-4
    amin      1.0    2.0    7.0    3.0
    20%       1.8    2.8    7.4    4.2
    median    3.0    4.0    8.0    6.0
    80%       4.2    5.2    8.6    7.8
    amax      5.0    6.0    9.0    9.0
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    用agg()函数可以聚合实现describe()相同的效果,只要将函数组合在一起传给agg()即可。所以我们可以根据自己的需要来增加或裁剪describe()中的内容。
    上面的例子中,pd.Series.quantile()是pandas中求分位数的函数,默认是求中位数,指定q参数可以计算不同的分位数。
    partial()是Python的functools内置库中的函数,作用是给传入它的函数固定参数值,如上面分别固定quantile()的q参数为0.2/0.8。
    分组聚合结合使用

    # 先用groupby()分组再用agg()聚合
    res12 = df.groupby('Col-1').agg([np.min, np.max])
    print('-' * 40, '\n', res12, sep='')
    # 分组后只聚合某一列
    res13 = df.groupby('Col-1').agg({'Col-2': [np.min, np.mean, np.max]})
    print('-' * 40, '\n', res13, sep='')
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    ----------------------------------------
          Col-2      Col-3      Col-4     
           amin amax  amin amax  amin amax
    Col-1                                 
    1         2    2     9    9     3    3
    3         4    4     8    8     6    6
    5         6    6     7    7     9    9
    ----------------------------------------
          Col-2          
           amin mean amax
    Col-1                
    1         2  2.0    2
    3         4  4.0    4
    5         6  6.0    6
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    agg()经常接在分组函数groupby()的后面使用,先分组再聚合,分组之后可以对所有组聚合,也可以只聚合需要聚合的组。
    groupby()详解参考:Pandas知识点-详解分组函数groupby

    res14 = df.groupby('Col-1').agg(
        c2_min=pd.NamedAgg(column='Col-2', aggfunc='min'),
        c3_min=pd.NamedAgg(column='Col-3', aggfunc='min'),
        c2_sum=pd.NamedAgg(column='Col-2', aggfunc='sum'),
        c3_sum=pd.NamedAgg(column='Col-3', aggfunc='sum'),
        c4_sum=pd.NamedAgg(column='Col-4', aggfunc='sum')
    )
    print('-' * 40, '\n', res14, sep='')
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    ----------------------------------------
           c2_min  c3_min  c2_sum  c3_sum  c4_sum
    Col-1                                        
    1           2       9       2       9       3
    3           4       8       4       8       6
    5           6       7       6       7       9
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    pd.NamedAgg可以对聚合进行更精准的定义,它包含column和aggfunc两个定制化的字段,column设置用于聚合的列,aggfunc设置用于聚合的函数。
    借助pd.NamedAgg,可以给column和aggfunc的组合自定义命名,自定义命名体现为聚合结果中的列名。
    以上就是pandas中聚合函数agg()的用法介绍和分析,如果本文的内容对你有帮助,欢迎点赞、评论、收藏,也可以关注和联系我一起交流讨论。

    参考文档:
    [1] pandas中文网:https://www.pypandas.cn/docs/

  • 相关阅读:
    SpringMVC快速入门
    Linux | 二级页表的虚拟地址是怎么转换的?
    前端笔试练习题——JS7 无重复数组、JS8 数组排序
    C到C++/编译过程/链接方式/内存模型/STL
    d合并json
    嵌入式Qt-控制硬件:滑动条控制RGB灯
    改进YOLO系列 | YOLOv5/v7 引入 Dynamic Snake Convolution | 动态蛇形卷积
    【算法基础】双指针
    Win2016服务器DNS服务搭建
    日常--windows11右键切换回win10
  • 原文地址:https://blog.csdn.net/weixin_43790276/article/details/125963758