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函數,見下一章。