zoukankan      html  css  js  c++  java
  • 5-Pandas数据分组的函数应用(df.apply()、df.agg()和df.transform()、df.applymap())

    将自己定义的或其他库的函数应用于Pandas对象,有以下3种方法:

    1. apply():逐行或逐列应用该函数
    2. agg()和transform():聚合和转换
    3. applymap():逐元素应用函数

    一 、apply()

    其中:设置axis = 1参数,可以逐行进行操作;默认axis=0,即逐列进行操作;

        对于常见的描述性统计方法,可以直接使用一个字符串进行代替,例df.apply('mean')等价于df.apply(np.mean);

    >>> df = pd.read_excel('./input/class.xlsx)
    >>> df = df[['score_math','score_music']]
    >>> df
       score_math  score_music
    0          95           79
    1          96           90
    2          85           85
    3          93           92
    4          84           90
    5          88           70
    6          59           89
    7          88           86
    8          89           74
    
    #对音乐课和数学课逐列求成绩平均分
    >>> df.apply(np.mean)
    score_math     86.333333
    score_music    83.888889
    dtype: float64
    >>> type(df.apply(np.mean))
    <class 'pandas.core.series.Series'>
    
    >>> df['score_math'].apply('mean')
    86.33333333333333
    >>> type(df['score_math'].apply(np.mean))
    <class 'pandas.core.series.Series'>
    
    #逐行求每个学生的平均分
    >>> df.apply(np.mean,axis=1)
    0    87.0
    1    93.0
    2    85.0
    3    92.5
    4    87.0
    5    79.0
    6    74.0
    7    87.0
    8    81.5
    dtype: float64
    >>> type(df.apply(np.mean,axis=1))
    <class 'pandas.core.series.Series'>

      apply()的返回结果与所用的函数是相关的

    • 返回结果是Series对象:如上述例子应用的均值函数,就是每一行或每一列返回一个值;
    • 返回大小相同的DataFrame:如下面自定的lambda函数。
    #其中的x可以看作是每一类的Series对象
    >>> df.apply(lambda x: x - 5)
       score_math  score_music
    0          90           74
    1          91           85
    2          80           80
    3          88           87
    4          79           85
    5          83           65
    6          54           84
    7          83           81
    8          84           69
    >>> type(df.apply(lambda x: x - 5))
    <class 'pandas.core.frame.DataFrame'>

    二、数据聚合agg()

    • 数据聚合agg()指任何能够从数组产生标量值的过程;
    • 相当于apply()的特例,可以对pandas对象进行逐行或逐列的处理;
    • 能使用agg()的地方,基本上都可以使用apply()代替。

    例:

    1)对两门课逐列求平均分

    >>> df.agg('mean')
    score_math     86.333333
    score_music    83.888889
    dtype: float64
    >>> df.apply('mean')
    score_math     86.333333
    score_music    83.888889
    dtype: float64

     2)应用多个函数,可将函数放于一个列表中;

    例:对两门课分别求最高分与最低分

    >>> df.agg(['max','min'])
         score_math  score_music
    max          96           92
    min          59           70
    >>> df.apply([np.max,'min'])
          score_math  score_music
    amax          96           92
    min           59           70

      3)使用字典可以对特定列应用特定及多个函数

    例:对数学成绩求均值和最小值,对音乐课求最大值

    >>> df.agg({'score_math':['mean','min'],'score_music':'max'})
          score_math  score_music
    max          NaN         92.0
    mean   86.333333          NaN
    min    59.000000          NaN

    三、数据转换transform()

    特点使用一个函数后,返回相同大小的Pandas对象

    与数据聚合agg()的区别

    1. 数据聚合agg()返回的是对组内全量数据的缩减过程;
    2. 数据转换transform()返回的是一个新的全量数据。

    注意:df.transform(np.mean)将报错,转换是无法产生聚合结果的

    #将成绩减去各课程的平均分,使用apply、agg、transfrom都可以实现
    >>> df.transform(lambda x:x-x.mean())
    >>> df.apply(lambda x:x-x.mean())
    >>> df.agg(lambda x:x-x.mean())
       score_math  score_music
    0    8.666667    -4.888889
    1    9.666667     6.111111
    2   -1.333333     1.111111
    3    6.666667     8.111111
    4   -2.333333     6.111111
    5    1.666667   -13.888889
    6  -27.333333     5.111111
    7    1.666667     2.111111
    8    2.666667    -9.888889

    应用多个函数时,将返回于原始DataFrame大小不同的DataFrame,返回结果中:

    • 在列索引上第一级别是原始列名
    • 在第二级别上是转换的函数名
    >>> df.transform([lambda x:x-x.mean(),lambda x:x/10])
      score_math          score_music
        <lambda> <lambda>    <lambda> <lambda>
    0   8.666667      9.5   -4.888889      7.9
    1   9.666667      9.6    6.111111      9.0
    2  -1.333333      8.5    1.111111      8.5
    3   6.666667      9.3    8.111111      9.2
    4  -2.333333      8.4    6.111111      9.0
    5   1.666667      8.8  -13.888889      7.0
    6 -27.333333      5.9    5.111111      8.9
    7   1.666667      8.8    2.111111      8.6
    8   2.666667      8.9   -9.888889      7.4

    四、applymap()

    applymap()对pandas对象逐元素应用某个函数,成为元素级函数应用;

    map()的区别:

    • applymap()是DataFrame的实例方法
    • map()是Series的实例方法

     例:对成绩保留小数后两位

    >>> df.applymap(lambda x:'%.2f'%x)
      score_math score_music
    0      95.00       79.00
    1      96.00       90.00
    2      85.00       85.00
    3      93.00       92.00
    4      84.00       90.00
    5      88.00       70.00
    6      59.00       89.00
    7      88.00       86.00
    8      89.00       74.00
    
    >>> df['score_math'].map(lambda x:'%.2f'%x)
    0    95.00
    1    96.00
    2    85.00
    3    93.00
    4    84.00
    5    88.00
    6    59.00
    7    88.00
    8    89.00
    Name: score_math, dtype: object
    

     从上述例子可以看出,applymap()操作实际上是对每列的Series对象进行了map()操作

    通过以上分析我们可以看到,applyaggtransform三种方法都可以对分组数据进行函数操作,但也各有特色,总结如下:

    • apply中自定义函数对每个分组数据单独进行处理,再将结果合并;整个DataFrame的函数输出可以是标量、Series或DataFrame;每个apply语句只能传入一个函数;
    • agg可以通过字典方式指定特征进行不同的函数操作,每一特征的函数输出必须为标量;
    • transform不可以通过字典方式指定特征进行不同的函数操作,但函数运算单位也是DataFrame的每一特征,每一特征的函数输出可以是标量或者Series,但标量会被广播。
  • 相关阅读:
    如何实现九宫格布局-----源码如下
    查询出的数据记录字段要与实体类中的属性名一致
    2016/12/14---- C3P0
    Spring的数据库操作---- Spring框架对JDBC的整合 ---- 初始化JdbcTemplate对象
    Spring的数据库操作---- Spring框架对JDBC的整合---- 初始化连接池数据源对象
    Spring的数据库操作---- Spring框架对JDBC的整合---- Spring的数据库操作
    Spring的数据库操作---- Spring框架对JDBC的整合---- spring集成jdbc概述
    Spring的AOP机制---- AOP的注解配置---- AOP的注解配置
    Spring的AOP机制---- 切入点表达式---- 切入点表达式
    Spring的AOP机制---- AOP环绕通知---- AOP环绕通知
  • 原文地址:https://www.cnblogs.com/Cheryol/p/13451562.html
Copyright © 2011-2022 走看看