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);

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
>>> 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函数。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
#其中的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)对两门课逐列求平均分

1
2
3
4
5
6
7
8
>>> 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)应用多个函数,可将函数放于一个列表中;

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

1
2
3
4
5
6
7
8
>>> 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)使用字典可以对特定列应用特定及多个函数;

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

1
2
3
4
5
>>> 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)将报错,转换是无法产生聚合结果的

1
2
3
4
5
6
7
8
9
10
11
12
13
14
#将成绩减去各课程的平均分,使用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,返回结果中:

  • 在列索引上第一级别是原始列名
  • 在第二级别上是转换的函数名
1
2
3
4
5
6
7
8
9
10
11
12
>>> 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的实例方法

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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
>>> 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,但标量会被广播。

 


免责声明!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系本站邮箱yoyou2525@163.com删除。



 
粤ICP备18138465号  © 2018-2025 CODEPRJ.COM