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,但標量會被廣播。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM