1. 程式人生 > >panda資料處理:groupby()函式

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