panda資料處理:groupby()函式
groupby()是pandas庫中DataFrame結構的函式,最近在看用Movielens資料集進行關聯分析的教程時,發現用到了groupby()函式,覺得該函式功能很強大,經常用在for迴圈結構中用於提取資料,故對該函式一些常用的方法進行一些記錄。
先建立一個DataFrame物件df
import pandas as pd df=pd.DataFrame({'name':['a','b','c','d','e'],'age':[10,15,20,15,20],'sex':[True,True,False,True,False]}) df >>> name age sex 0 a 10 True 1 b 15 True 2 c 20 False 3 d 15 True 4 e 20 False
1.資料分組
依據某個columns對整個DataFrame物件分組
df_1=df.groupby(df['sex']) list(df_1) >>> [(False, name age sex 2 c 20 False 4 e 23 False), (True, name age sex 0 a 10 True 1 b 15 True 3 d 17 True)]
依據某個columns對另一個columns資料分組
df_1=df['age'].groupby(df['sex'])
list(df_1)
>>> [(False,
2 20
4 23
Name: age, dtype: int64),
(True, 0 10
1 15
3 17
Name: age, dtype: int64)]
這個過程還有另外一種語法
df_1=df.groupby(df['sex'])['age']
list(df_1)
>>> [(False, 2 20
4 23
Name: age, dtype: int64),
(True, 0 10
1 15
3 17
Name: age, dtype: int64)]
當然,也可以同時對多個columns資料進行分組,以第一種語法方式為例,此時要注意多個columns的書寫方式
df_1=df[['age','name']].groupby(df['sex'])
list(df_1)
>>> [(False, age name
2 20 c
4 23 e),
(True, age name
0 10 a
1 15 b
3 17 d)]
也可以依據多個columns對某個columns資料分組,注意這裡groupby函式內columns的寫法,不能再像上面那樣了
df_1=df['name'].groupby([df['sex'],df['age']])
list(df_1)
>>> [((False, 20), 2 c
Name: name, dtype: object),
((False, 23), 4 e
Name: name, dtype: object),
((True, 10), 0 a
Name: name, dtype: object),
((True, 15), 1 b
Name: name, dtype: object),
((True, 17), 3 d
Name: name, dtype: object)]
除了依據DataFrame結構中已有的columns對資料進行分組,還可以通過外部設定的columns對DataFrame資料進行分組
import numpy as np
education=np.array(['mid school','high school','university','high school','university'])
df_1=df.groupby([education])
list(df_1)
>>> [('high school', name age sex
1 b 15 True
3 d 17 True),
('mid school', name age sex
0 a 10 True),
('university', name age sex
2 c 20 False
4 e 23 False)]
通過groupby函式來分組時,還有一些別具創意的分組方式,任何被當做分組鍵的函式都會在各個索引值上被呼叫一次,其返回值就會被用作分組名稱。例如對於所用的df,給它加上索引值index(國籍),然後依據國家名稱英文字元的個數來分組
df.index=['China','Russia','USA','English','Japan']
df.groupby(len).sum()
>>> age sex
3 20 False
5 30 True
6 15 True
7 15 True
可以看到, ‘China’和'Japan'字母長度均為5,故在計算‘age’和'sex'時將其對應的值求和了,'age'不具有求和性質,未參與計算。
2.對分組進行迭代,生成字典
for index,group in df.groupby(df['sex'])['age']:
print(index)
print(group)
>>> False
2 20
4 20
Name: age, dtype: int64
True
0 10
1 15
3 15
Name: age, dtype: int64
在上面的程式中,index的輸出為 ['False' , 'True'],group的輸出結果為 [ ['20','20'] , ['10','15','15'] ]。一種常見的情況為用index、group的值生成字典。
dic=dict((index,frozenset(group.values))for index,group in df.groupby(df['sex'])['age'])
dic
>>> {False: frozenset({20}), True: frozenset({10, 15})}
在生成字典時,也會有多重鍵的情況,可以用以下方式
dic=dict(((index_1,index_2),frozenset(group.values))for (index_1,index_2),group in df['age'].groupby([df['sex'],df['age']]))
dic
>>> {(False, 20): frozenset({20}),
(True, 10): frozenset({10}),
(True, 15): frozenset({15})}
也可以用這種更為簡潔的方式
dic=dict((index,frozenset(group.values))for index,group in df['age'].groupby([df['sex'],df['age']]))
dic
>>> {(False, 20): frozenset({20}),
(True, 10): frozenset({10}),
(True, 15): frozenset({15})}
還有另一種方式來生成字典
dic=dict( list(df.groupby('sex')))
dic
>>> {False: name age sex
2 c 20 False
4 e 20 False,
True: name age sex
0 a 10 True
1 b 15 True
3 d 15 True}
dic[False]['name']
>>> 2 c
4 e
Name: name, dtype: object
這種對整個df生成字典的方式,字典每個鍵對應的值仍然為一個DataFrame結構。按照這種方式當然也可以用df中某個columns 生成字典。
3.求和、平均計算
資料處理時經常在groupby之後用到求和、平均計算,所以這裡也順帶提一下。
計算平均的過程為
df.groupby('sex')['age'].mean()
>>> sex
False 20.000000
True 13.333333
Name: age, dtype: float64
求和的過程為
df.groupby('sex')['age'].sum()
>>> sex
False 40
True 40
Name: age, dtype: int64
還有一種就是對DataFrame整個結構中各行或各列計算平均或求和,這裡先引入pandas中軸(axis)的定義,在DataFrame中有axis=0和axis=1兩種情況,axis=0表示遍歷所有的行,不能理解為axis=0表示對列的操作,同樣的,axis=1表示遍歷所有的列。另外,在numpy庫中也有關鍵字axis,且用法與pandas中一致。那麼通過使用axis,求和、計算平均的過程可以為
df.sum(axis=1)
>>> 0 11.0
1 16.0
2 20.0
3 16.0
4 20.0
dtype: float64
df.sum(axis=0)
>>> name abcde
age 80
sex 3
dtype: object
df.mean(axis=0)
>>> age 16.0
sex 0.6
dtype: float64