在數(shù)據(jù)分析中,經(jīng)常會遇到這樣的情況:根據(jù)某一列(或多列)標(biāo)簽把數(shù)據(jù)劃分為不同的組別,然后再對其進行數(shù)據(jù)分析。比如,某網(wǎng)站對注冊用戶的性別或者年齡等進行分組,從而研究出網(wǎng)站用戶的畫像(特點)。在Pandas中,要完成數(shù)據(jù)的分組操作,需要使用groupby()函數(shù),它和SQL的GROUPBY操作非常相似。 在劃分出來的組(group)上應(yīng)用一些統(tǒng)計函數(shù),從而達到數(shù)據(jù)分析的目的,比如對分組數(shù)據(jù)進行聚合、轉(zhuǎn)換,或者過濾。這個過程主要包含以下三步: 拆分(Spliting):表示對數(shù)據(jù)進行分組; 應(yīng)用(Applying):對分組數(shù)據(jù)應(yīng)用聚合函數(shù),進行相應(yīng)計算; 合并(Combining):最后匯總計算結(jié)果。 下面對groupby()函數(shù)的應(yīng)用過程進行具體的講解。 創(chuàng)建DataFrame對象首先我們創(chuàng)建一個DataFrame對象,下面數(shù)據(jù)描述了某班學(xué)生,計算機選修課的考試成績: import pandas as pd import numpy as np data = {'Name': ['John', 'Helen', 'Sona', 'Ella'], 'score': [82, 98, 91, 87], 'option_course': ['C#','Python','Java','C']} df = pd.DataFrame(data) print(df) 1234567復(fù)制代碼類型:[python] 輸出結(jié)果: Name score option_course0 John 82 C#1 Helen 98 Python2 Sona 91 Java3 Ella 87 C12345復(fù)制代碼類型:[python] 創(chuàng)建groupby分組對象使用groupby()可以沿著任意軸分組。您可以把分組時指定的鍵(key)作為每組的組名,方法如下所示: df.groupby("key") df.groupby("key",axis=1) df.groupby(["key1","key2"]) 通過上述方法對DataFrame對象進行分組操作: import pandas as pdimport numpy as np data = {'Name': ['John', 'Helen', 'Sona', 'Ella'], 'score': [82, 98, 91, 87], 'option_course': ['C#','Python','Java','C']} df = pd.DataFrame(data) print(df)#生成分組groupby對象print(df.groupby('score'))123456789復(fù)制代碼類型:[python] 輸出結(jié)果: <pandas.core.groupby.generic.DataFrameGroupBy object at 0x0000021DE9A89640>1復(fù)制代碼類型:[python] 查看分組結(jié)果1)groups查看分組結(jié)果 通過調(diào)用groups屬性查看分組結(jié)果: import pandas as pdimport numpy as np data = {'Name': ['John', 'Helen', 'Sona', 'Ella'], 'score': [82, 98, 91, 87], 'option_course': ['C#','Python','Java','C']} df = pd.DataFrame(data)#查看分組print(df.groupby('score').groups)12345678復(fù)制代碼類型:[python] 輸出結(jié)果: {82: Int64Index([0], dtype='int64'), 87: Int64Index([3], dtype='int64'), 91: Int64Index([2], dtype='int64'), 98: Int64Index([1], dtype='int64')}1234復(fù)制代碼類型:[python] 2)多個列標(biāo)簽分組 當(dāng)然也可以指定多個列標(biāo)簽進行分組,示例如下: import pandas as pdimport numpy as np data = {'Name': ['John', 'Helen', 'Sona', 'Ella'], 'score': [82, 98, 91, 87], 'option_course': ['C#','Python','Java','C']} df = pd.DataFrame(data)#查看分組print(df.groupby(['Name','score']).groups)12345678復(fù)制代碼類型:[python] 輸出結(jié)果: {('Ella', 87): Int64Index([3], dtype='int64'), ('Helen', 98): Int64Index([1], dtype='int64'), ('John', 82): Int64Index([0], dtype='int64'), ('Sona', 91): Int64Index([2], dtype='int64')}1234復(fù)制代碼類型:[python] 通過get_group()方法可以選擇組內(nèi)的具體數(shù)據(jù)項: import pandas as pdimport numpy as np data = {'Name': ['John', 'Helen', 'Sona', 'Ella'], 'score': [82, 98, 91, 87], 'option_course': ['C#','Python','Java','C']} df = pd.DataFrame(data)#根據(jù)score來分組grouped=df.groupby('score')#根據(jù)對應(yīng)組的數(shù)據(jù)值,選擇一個組print(grouped.get_group(91))12345678910復(fù)制代碼類型:[python] 輸出結(jié)果: Name score option_course2 Sona 91 Java12復(fù)制代碼類型:[python] 遍歷分組數(shù)據(jù)通過以下方法來遍歷分組數(shù)據(jù),示例如下: import pandas as pdimport numpy as np data = {'Name': ['John', 'Helen', 'Sona', 'Ella'], 'score': [82, 98, 91, 87], 'option_course': ['C#','Python','Java','C']} df = pd.DataFrame(data)#查看分組grouped=df.groupby('score')for label, option_course in grouped:#其中key代表分組后字典的鍵,也就是score print(label)#字典對應(yīng)的值選修的科目 print(option_course)12345678910111213復(fù)制代碼類型:[python] 輸出結(jié)果: 82 Name score option_course0 John 82 C#87 Name score option_course3 Ella 87 C91 Name score option_course2 Sona 91 Java98 Name score option_course1 Helen 98 Python123456789101112復(fù)制代碼類型:[python] 如上所示,groupby對象的組名稱與score中的的元素值一一對應(yīng)。 應(yīng)用聚合函數(shù)當(dāng)您在創(chuàng)建groupby對象時,通過agg()函數(shù)可以對分組對象應(yīng)用多個聚合函數(shù): import pandas as pd import numpy as np data = {'name': ['John', 'Helen', 'Sona', 'Ella'], 'score': [82, 98, 91, 87], 'option_course': ['C#','Python','Java','C']} df = pd.DataFrame(data) grouped=df.groupby('name')#應(yīng)用一個聚合函數(shù)求均值print(grouped['score']).agg(np.mean)123456789復(fù)制代碼類型:[python] 輸出結(jié)果: name Ella 87Helen 98John 82Sona 91Name: score, dtype: int64123456復(fù)制代碼類型:[python] 當(dāng)然,您也可以一次性應(yīng)有多個聚合函數(shù),示例如下: import pandas as pdimport numpy as np data = {'name': ['John', 'Helen', 'Sona', 'Ella'], 'score': [82, 98, 91, 87], 'option_course': ['C#','Python','Java','C']} df = pd.DataFrame(data) grouped=df.groupby('name') print(grouped['score'].agg([np.size,np.mean,np.std]))12345678復(fù)制代碼類型:[python] 輸出結(jié)果: size mean std name Ella 1 87 NaN Helen 1 98 NaN John 1 82 NaN Sona 1 91 NaN123456復(fù)制代碼類型:[python] 組的轉(zhuǎn)換操作在組的行或列上可以執(zhí)行轉(zhuǎn)換操作,最終會返回一個與組大小相同的索引對象。示例如下: import pandas as pdimport numpy as np df = pd.DataFrame({'種類':['水果','水果','水果','蔬菜','蔬菜','肉類','肉類'], '產(chǎn)地':['朝鮮','中國','緬甸','中國','菲律賓','韓國','中國'], '水果':['橘子','蘋果','哈密瓜','番茄','椰子','魚肉','牛肉'], '數(shù)量':[3,5,5,3,2,15,9], '價格':[2,5,12,3,4,18,20]})#分組求均值,水果、蔬菜、肉類#對可執(zhí)行計算的數(shù)值列求均值print(df.groupby('種類').transform(np.mean))#transform()直接應(yīng)用demean,實現(xiàn)去均值操作demean = lambda arr:arr-arr.mean() print(df.groupby('種類').transform(demean))#自定義函數(shù)# 返回分組的前n行數(shù)據(jù)def get_rows(df,n): #從1到n行的所有列 return df.iloc[:n,:]#分組后的組名作為行索引print(df.groupby('種類').apply(get_rows,n=1))1234567891011121314151617181920復(fù)制代碼類型:[python] 輸出結(jié)果: 數(shù)量 價格0 4.333333 6.3333331 4.333333 6.3333332 4.333333 6.3333333 2.500000 3.5000004 2.500000 3.5000005 12.000000 19.0000006 12.000000 19.000000 數(shù)量 價格0 -1.333333 -4.3333331 0.666667 -1.3333332 0.666667 5.6666673 0.500000 -0.5000004 -0.500000 0.5000005 3.000000 -1.0000006 -3.000000 1.000000 種類 產(chǎn)地 水果 數(shù)量 價格 種類 水果 0 水果 朝鮮 橘子 3 2肉類 5 肉類 韓國 魚肉 15 18蔬菜 3 蔬菜 中國 番茄 3 31234567891011121314151617181920212223復(fù)制代碼類型:[python] 組的數(shù)據(jù)過濾操作通過filter()函數(shù)可以實現(xiàn)數(shù)據(jù)的篩選,該函數(shù)根據(jù)定義的條件過濾數(shù)據(jù)并返回一個新的數(shù)據(jù)集。 下面,篩選出參加比賽超過兩次的球隊(包含兩次): import pandas as pdimport numpy as np data = {'Team': ['Riders', 'Riders', 'Devils', 'Devils', 'Kings', 'kings', 'Kings', 'Kings', 'Riders', 'Royals', 'Royals', 'Riders'], 'Rank': [1, 2, 2, 3, 3,4 ,1 ,1,2 , 4,1,2], 'Year': [2014,2015,2014,2015,2014,2015,2016,2017,2016,2014,2015,2017], 'Points':[874,789,863,663,741,802,756,788,694,701,812,698]} df = pd.DataFrame(data)#定義lambda函數(shù)來篩選數(shù)據(jù)print (df.groupby('Team').filter(lambda x: len(x) >= 2))12345678910復(fù)制代碼類型:[python] 輸出結(jié)果: Team Rank Year Points0 Riders 1 2014 8741 Riders 2 2015 7894 Kings 3 2014 7416 Kings 1 2016 7567 Kings 1 2017 7888 Riders 2 2016 69411 Riders 2 2017 698 |
|
來自: 碼農(nóng)9527 > 《Python》