5-Pandas数据分组的函数应用(df.apply()、df.agg()和df.transform()、df.applymap())
阅读原文时间:2023年07月08日阅读:1

将自己定义的或其他库的函数应用于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&nbsp; 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&nbsp; score_music

max          96           92

min          59           70

>>> df.``apply``([np.``max``,``'min'``])

score_math&nbsp; 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&nbsp; 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&nbsp; 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&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; score_music

<``lambda``> <``lambda``>&nbsp;&nbsp;&nbsp; <``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,但标量会被广播。

手机扫一扫

移动阅读更方便

阿里云服务器
腾讯云服务器
七牛云服务器