pandas groupby 詳解
-
Name Brand Cloth Count
-
girl uniql sweater 3
-
girl etam suit 1
-
girl etam pants 1
-
girl lagogo jacket 2
-
boy pants 2
-
boy hailan t-shirt 1
-
mother hengyuanxiang coat 2
-
mother hengyuanxiang sweater 1
-
mother coat 1
-
father hailan t-shirt 2
-
father hailan sweater 1
-
father hailan pants 3
本文資料來源如上,Name:在家庭中的身份, Brand:衣服品牌, ClothType:衣服數量,Count:衣服數量
import pandas as pd data=pd.read_excel('testdata.xlsx')
如果是csv檔案:
import pandas as pd data=pd.read_csv('testdata.csv',sep=',')
檢視data的內容:
-
data
-
Out[1]:
-
Name Brand Cloth Count
-
0 girl uniql sweater 3
-
1 girl etam suit 1
-
2 girl etam pants 1
-
3 girl lagogo jacket 2
-
4 boy NaN pants 2
-
5 boy hailan t-shirt 1
-
6 mother hengyuanxiang coat 2
-
7 mother hengyuanxiang sweater 1
-
8 mother NaN coat 1
-
9 father hailan t-shirt 2
-
10 father hailan sweater 1
-
11 father hailan pants 3
獲取列名:
-
data.columns
-
Out[2]: Index(['Name', 'Brand', 'Cloth', 'Count'], dtype='object')
-
data.columns[0]
-
Out[2]: 'Name'
-
data.columns[1]
-
Out[3]: 'Brand'
獲取index:
-
data.index
-
Out[3]: RangeIndex(start=0, stop=12, step=1)
從0開始,到12停,不包括12.所以一共有12行資料
獲取values:
-
data.values
-
Out[4]:
-
array([['girl', 'uniql', 'sweater', 3],
-
['girl', 'etam', 'suit', 1],
-
['girl', 'etam', 'pants', 1],
-
['girl', 'lagogo', 'jacket', 2],
-
['boy', nan, 'pants', 2],
-
['boy', 'hailan', 't-shirt', 1],
-
['mother', 'hengyuanxiang', 'coat', 2],
-
['mother', 'hengyuanxiang', 'sweater', 1],
-
['mother', nan, 'coat', 1],
-
['father', 'hailan', 't-shirt', 2],
-
['father', 'hailan', 'sweater', 1],
-
['father', 'hailan', 'pants', 3]], dtype=object)
獲取某一行:
-
data.values[1]
-
Out[5]: array(['girl', 'etam', 'suit', 1], dtype=object)
獲取某一格:
-
data.values[1][2]
-
Out[6]: 'suit'
按某一列關鍵字分組:
-
gp=data.groupby('Brand')#寫data.groupby(data['Brand'])也是一樣的
-
gp
-
Out[10]: <pandas.core.groupby.DataFrameGroupBy object at 0x0000000008309B38>
-
type(gp)
-
Out[11]: pandas.core.groupby.DataFrameGroupBy
gp是一個把dataframe groupby以後的物件,它實際上還沒有進行任何計算,只是一個暫時儲存的容器。
對這個暫時儲存的容器進行計數,因為是按'Brand'分的組,:
-
gp.count()
-
Out[13]:
-
Name Cloth Count
-
Brand
-
etam 2 2 2
-
hailan 4 4 4
-
hengyuanxiang 2 2 2
-
lagogo 1 1 1
-
uniql 1 1 1
看到按'Brand'分組後的這個結果,Name,Cloth,Count列在每種Brand所對應行的數字都一樣,比如:2 2 2.可以理解為每種Brand各有多少行資料,把這個行數顯示在所有列。
因為我們選擇時是data.groupby(),而不是data['Count'].groupby()
p.s.:可以看到分組計數後的index是'Brand‘,這是因為分組是按'Brand’欄位分的
-
gp.count().index
-
Out[14]: Index(['etam', 'hailan', 'hengyuanxiang', 'lagogo', 'uniql'], dtype='object', name='Brand')
想知道每種Brand的衣服有多少人穿多少種,其實只看 Count列就行了。
比如father雖然有2件T-shirt,1件sweater,3件pants,還是算1個人穿3種hailan。boy有一件hailan的t-shirt,算1個人穿1種hailan。所以hailan對應4。 總之,count()函式可以理解為對Count列去重的和。
-
gp1=data['Count'].groupby(data['Brand'])
-
gp1.count() #和gp1.size()結果一樣
-
Out[20]:
-
Brand
-
etam 2
-
hailan 4
-
hengyuanxiang 2
-
lagogo 1
-
uniql 1
-
Name: Count, dtype: int64
想求某品牌被人均擁有的件數的平均值:
比如hailan就是father的2件T恤,1件毛衣,3條褲子,還有boy的1件T恤。 (2+1+3+1)/4=1.75。 分母4可以理解為剛才所說的 gp1.count() :每種Brand的衣服有多少人穿多少種
比如hengyuanxiang就是mother的2件大衣,1件毛衣 ,(2+1)/2=1.5
-
gp1.mean()
-
Out[21]:
-
Brand
-
etam 1.00
-
hailan 1.75
-
hengyuanxiang 1.50
-
lagogo 2.00
-
uniql 3.00
-
Name: Count, dtype: float64
說明:type(gp1.mean()) 是 Series型別。之所以index叫'Brand',是因為原datafram是按'Brand' groupby的
想求某品牌被每人擁有的件數:(與“”想知道每種Brand的衣服有多少人穿多少種“ .count( )演算法的區別在於 不去重)
在Count列上加和
-
gp1.agg(sum) #就是 data['Count'].groupby(data['Brand']).agg(sum) , agg裡也可以寫'sum',與不加單引號等效
-
Out[5]:
-
Brand
-
etam 2
-
hailan 7
-
hengyuanxiang 3
-
lagogo 2
-
uniql 3
-
Name: Count, dtype: int64
綜上所述可以觀察出,gp1.mean()操作的結果等於 gp1.agg(sum)/gp1.count()
遍歷分組:
-
for name,group in data.groupby(data['Brand']):
-
print(name)
-
print(group)
-
etam
-
Name Brand Cloth Count
-
1 girl etam suit 1
-
2 girl etam pants 1
-
hailan
-
Name Brand Cloth Count
-
5 boy hailan t-shirt 1
-
9 father hailan t-shirt 2
-
10 father hailan sweater 1
-
11 father hailan pants 3
-
hengyuanxiang
-
Name Brand Cloth Count
-
6 mother hengyuanxiang coat 2
-
7 mother hengyuanxiang sweater 1
-
lagogo
-
Name Brand Cloth Count
-
3 girl lagogo jacket 2
-
uniql
-
Name Brand Cloth Count
-
0 girl uniql sweater 3
由上可以看出,brand為NaN 的衣服並沒有被分組,自動忽略不計了。
對於由DataFrame產生的GroupBy物件,如果用一個(單個字串)或一組(字串陣列)列名對其進行索引,就能實現選取部分列進行聚合的目的,即:
寫法一:
-
data.groupby('Brand')['Count'].sum()#等價於data.groupby('Brand')['Count'].agg(sum),等價於data.groupby('Brand')['Count'].agg('sum')#等價於data.groupby('Brand').agg('sum')['Count'],等價於data.groupby('Brand').agg(sum)['Count'],等價於data.groupby('Brand').sum()['Count']
-
Out[13]:
-
Brand
-
etam 2
-
hailan 7
-
hengyuanxiang 3
-
lagogo 2
-
uniql 3
-
Name: Count, dtype: int64
這和寫法二:
-
data['Count'].groupby(data['Brand']).sum()
-
Out[19]:
-
Brand
-
etam 2
-
hailan 7
-
hengyuanxiang 3
-
lagogo 2
-
uniql 3
-
Name: Count, dtype: int64
是等效的
注意寫法一里面的'Brand'不用必須寫成(當然也可以寫成)data['Brand'],是因為data.groupby()由於是對data這個dataframe呼叫的方法,所以能識別出data的欄位'Brand'。但是寫法二是對data['Count'] 這個Series物件呼叫的groupby,不認識'Brand',只認識data['Brand'],如果寫法二還寫成.groupby('Brand')就會報錯。
雙索引分組:
想知道每人擁有每種品牌的衣服多少種類型(型別就是Cloth欄位,寫成ClothType大家更容易理解哈):
-
data.groupby(['Name','Brand'])['Count'].count() #和寫.size( )效果一樣
-
Out[31]:
-
Name Brand
-
boy hailan 1
-
father hailan 3
-
girl etam 2
-
lagogo 1
-
uniql 1
-
mother hengyuanxiang 2
-
Name: Count, dtype: int64
從結果可以看出,對boy擁有的沒Brand的一條褲子,和mother沒牌子的一件大衣,都自動忽略不計了。
最後,感謝http://blog.csdn.net/leonis_v/article/details/51832916的分享