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