Pandas的數據分組以及分組聚合函數操作


1、數據分組

    分組基本操作案例:在水果列表里增加一列放入每種水果的平均值:

#進行數據分組,不顯示分組情況
df.groupby(by=['item'],axis =0).group #---axis =0表示列

#例如:求每組水果的價格和平均值(mean())
df.groupby(by=['item'],axis =0).mean()# 每種水果的平均價格
s =df.groupby(by=['item'],axis =0)['price'].mean()

 

    有NaN 映射關系不對!采用如下方式:

    s.to_dict()  # 將df數組轉為字典:{'a':'123','b':'345','c':'567'}

    創建一列,放入映射的值:df[‘mean’] = df['item'].map(s.to_dict()) 

    

2、統計函數

分組分析是指根據分組字段,將分析對象划分成不同的部分,以對比分析各組之間差異性的分析方法。分組分析常用的統計指標是計數、求和、平均值。
分組統計函數的語法格式如下:

groupby(by=[分組列1,分組列2,…])
        [統計列1,統計列2,…]
          .agg({統計列別名1:統計函數1,統計列別名2:統計函數2,…})

函數中的參數說明如下:

  • by:用於分組的列;
  • 中括號[ ]:用於統計的列;
  • agg:統計別名用於顯示統計值的名稱,統計函數用於統計數據,常用的統計函數有計數(size)、求和(sum)和均值(mean)。

【例 1 】在 Employee_income.xls 文件中包含有職工號(emp_id)、性別(sex)、年齡(age)、學歷(education)、參加工作時間(firstjob)、工作地區(region)、行業(industry)、職業(occupation)、月薪(salary)和月補貼(subsidy)等 10 列數據,要求分別按年齡、學歷分組統計人數,並求月薪的均值、最大值和最小值。
其示例代碼 test1 如下

import numpy as np
from pandas import DataFrame;
import pandas as pd
df = pd.read_excel('d:\data\emp_income\Employee_income.xls', sheet_name='emp_income')
age_result = df.groupby(by=['age'])['salary'].agg({
     '人數':np.size,
     '平均月薪':np.mean,
     '最高月薪':np.max,
     '最低月薪':np.min
})
print(age_result)
edu_result = df.groupby(by=['education'])['salary'].agg({
     '人數':np.size,
     '平均月薪':np.mean,
     '最高月薪':np.max,
     '最低月薪':np.min
})
print(edu_result)

運行輸出結果如下:

            人數   平均月薪   最高月薪    最低月薪
education
大專          4  3700.000000  4500       3000
本科          5  4700.000000  5000       4500
研究生        2  7099.500000  7699       6500
高中          7  2685.714286  3500       2000

3、高級數據聚合

    使用groupby分組后,也可以使用transform和apply提供自定義函數實現更多運算

  • df.groupby('item')['price'].sum()   <==>  df.groupby('item')['price'].apply(sum)
  • transform和apply都會進行運算,在transform和apply中傳入函數即可
  • transform和apply也可以傳入一個lambda表達式

apply自定義函數實現案例:

def my_mean(s): #---參數必須有一個,s傳入的是一個數組
    sum =0 
    for i in s:
      sum += i
    return sum/len(s) 
# apply(my_mean)調用自定義函數:my_mean
df.groupby(by=['item'],axis =0)['price'].apply(my_mean)

# transform 封裝了映射,transform返回值是經過映射的,可以直接往源數據里做匯總
df.groupby(by=['item'],axis =0)['price'].transform(my_mean)

4、分組聚合處理

在對數據進行分組之后,可以對分組后的數據進行聚合處理統計。

agg函數,agg的形參是一個函數會對分組后每列都應用這個函數。

import pandas as pd
import numpy as np
idx = [101,101,101,102,102,102,103,103,103]
idx += [101,102,103]
name = ["apple","pearl","orange", "apple","pearl","orange","apple","pearl","orange"]
name += ["apple"] * 3
price = [1.0,2.0,3.0,4.00,5.0,6.0,7.0,8.0,9.0]
price += [4] * 3
df0 = pd.DataFrame({ "fruit": name, "price" : price, "supplier" :idx})
print "*" * 30
print df0
print "*" * 30
dg1 =  df0.groupby(["fruit", "supplier"])
for n, g in dg1:
    print "multiGroup on:", n, "\n|",g ,"|"
print "*" * 30
print dg1.agg(np.mean)

程序的執行結果:

******************************
     fruit  price  supplier
0    apple      1       101
1    pearl      2       101
2   orange      3       101
3    apple      4       102
4    pearl      5       102
5   orange      6       102
6    apple      7       103
7    pearl      8       103
8   orange      9       103
9    apple      4       101
10   apple      4       102
11   apple      4       103
******************************
multiGroup on: ('apple', 101) 
|    fruit  price  supplier
0  apple      1       101
9  apple      4       101 |
...
multiGroup on: ('pearl', 103) 
|    fruit  price  supplier
7  pearl      8       103 |
******************************
                 price
fruit  supplier       
apple  101         2.5
       102         4.0
       103         5.5
orange 101         3.0
       102         6.0
       103         9.0
pearl  101         2.0
       102         5.0
       103         8.0

請注意水果apple的輸出。

  • agg應用均值、求和、最大等示例。
    import pandas as pd
    import numpy as np
    idx = [101,101,101,102,102,102,103,103,103]
    idx += [101,102,103] * 3
    name = ["apple","pearl","orange", "apple","pearl","orange","apple","pearl","orange"]
    name += ["apple"] * 3 + ["pearl"] * 3 + ["orange"] * 3
    price = [4.1,5.3,6.3,4.20,5.4,6.0,4.5,5.5,6.8]
    price += [4] * 3 + [5] * 3 + [6] * 3
    df0 = pd.DataFrame({ "fruit": name, "price" : price, "supplier" :idx})
    print "*" * 30
    print df0
    print "*" * 30
    dg1 =  df0.groupby(["fruit", "supplier"])
    print dg1.agg(np.mean)
    print "*" * 30
    print dg1.agg([np.mean, np.std, np.min, np.sum])
  • 程序執行結果:
    ******************************
         fruit  price  supplier
    0    apple    4.1       101
    ...
    17  orange    6.0       103
    ******************************
                     price
    fruit  supplier       
    apple  101        4.05
           102        4.10
           103        4.25
    orange 101        6.15
           102        6.00
           103        6.40
    pearl  101        5.15
           102        5.20
           103        5.25
    ******************************
                    price                     
                     mean       std amin   sum
    fruit  supplier                           
    apple  101       4.05  0.070711    4   8.1
           102       4.10  0.141421    4   8.2
           103       4.25  0.353553    4   8.5
    orange 101       6.15  0.212132    6  12.3
           102       6.00  0.000000    6  12.0
           103       6.40  0.565685    6  12.8
    pearl  101       5.15  0.212132    5  10.3
           102       5.20  0.282843    5  10.4
           103       5.25  0.353553    5  10.5
    

     

各列用不同的處理函數。需要在agg函數里以字典的形式給出,分組后的那列用那個函數處理。

import pandas as pd
import numpy as np
idx = [101,101,101,102,102,102,103,103,103]
idx += [101,102,103] * 3
name = ["apple","pearl","orange", "apple","pearl","orange","apple","pearl","orange"]
name += ["apple"] * 3 + ["pearl"] * 3 + ["orange"] * 3
price = [4.1,5.3,6.3,4.20,5.4,6.0,4.5,5.5,6.8]
price += [4] * 3 + [5] * 3 + [6] * 3
df0 = pd.DataFrame({ "fruit": name, "price" : price, "supplier" :idx})
print "*" * 30
print df0
print "*" * 30
dg1 =  df0.groupby(["fruit"])
print dg1.agg(np.mean)
print "*" * 30
print dg1.agg([np.mean, np.std, np.min, np.sum])
print "*" * 30
print dg1.agg({"price" : np.mean, "supplier" : np.max})

程序的執行結果:

******************************
     fruit  price  supplier
0    apple    4.1       101
1    pearl    5.3       101
2   orange    6.3       101
3    apple    4.2       102
4    pearl    5.4       102
5   orange    6.0       102
6    apple    4.5       103
7    pearl    5.5       103
8   orange    6.8       103
9    apple    4.0       101
10   apple    4.0       102
11   apple    4.0       103
12   pearl    5.0       101
13   pearl    5.0       102
14   pearl    5.0       103
15  orange    6.0       101
16  orange    6.0       102
17  orange    6.0       103
******************************
           price  supplier
fruit                     
apple   4.133333       102
orange  6.183333       102
pearl   5.200000       102
******************************
           price                      supplier                    
            mean       std amin   sum     mean       std amin  sum
fruit                                                             
apple   4.133333  0.196638    4  24.8      102  0.894427  101  612
orange  6.183333  0.325064    6  37.1      102  0.894427  101  612
pearl   5.200000  0.228035    5  31.2      102  0.894427  101  612
******************************
        supplier     price
fruit                     
apple        103  4.133333
orange       103  6.183333
pearl        103  5.200000

 

agg函數是對列而言的,如果打算對分組后列的數據進行處理可以使用tranform函數,見下一章。


免責聲明!

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



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