【pandas】groupby



2017年10月18日    Author:Guofei

文章归类: 0x12_Pandas与numpy    文章编号: 106

版权声明:本文作者是郭飞。转载随意,但需要标明原文链接,并通知本人
原文链接:https://www.guofei.site/2017/10/18/pandascleandata6.html


创建groupby

数据准备

import pandas as pd
import numpy as np
df=pd.DataFrame(np.arange(16).reshape(-1,4),columns=list('wxyz'))
df.loc[:,'w']=[0,0,1,1]
df.loc[:,'x']=[3,4,3,4]

1. groupby字段

可以groupby一个字段

df.groupby('w')

可以groupby多个字段

df.groupby(['w','x'])

2. groupby一个序列

一个1darray

random_values=np.random.randint(0,5,df.shape[0])
df.groupby(random_values)

一个Series

df.groupby(df.loc[:,'w'])

3. 函数/lambda

df.groupby(lambda n:n%3)

n是index,每次调用函数是输入1个

4. 在一个list中混用

df.groupby(['w',random_values,lambda n:n%3])

groupby取数

1. len

返回一个数字,分了多少组

len(df.groupby('w'))

2. key, df

for key,df_group in df.groupby('w'):
    print(key)#从0开始的编号
    print(df_group)#每个group的DataFrame

支持多种迭代接口

(key1,df1),(key2,df2)=df.groupby('w')

3. get_group

获取指定分组键对应的数据

数据准备:

import pandas as pd
import numpy as np
df=pd.DataFrame(np.arange(16).reshape(-1,4),columns=list('wxyz'))
df.loc[:,'w']=[0,0,1,1]
df.loc[:,'x']=list('abab')
w x y z
0 0 a 2 3
1 0 b 6 7
2 1 a 10 11
3 1 b 14 15
df.groupby(['w','x']).get_group((1,'a'))
w x y z
2 1 a 10 11

4. 取新列

df.groupby(['w','x'])['y']

也是一个groupby对象,只不过数据只有y这一列,用法与groupby完全相同:

for key,df_group in df.groupby(['w','x'])['z','y']:
    print(key)#从0开始的编号
    print(df_group)#每个group的DataFrame

groupby运算

通用方法

大多数DataFrame方法都可以用于groupby, 见于这里

agg()

import pandas as pd
import numpy as np
from scipy import stats
rv=stats.uniform()
df=pd.DataFrame(rv.rvs(size=(100,5)),columns=list('abcde'))
df.a=(df.a>0.5)*1
df.b=(df.b>0.5)*1

# 对所有列做多个agg
df.groupby('a')['d','e'].agg([np.sum,np.mean,np.min,np.max])

# 对每个列做不同的agg
df.groupby(['a','b'], as_index=False).agg({'c':[('mean_of_c','mean'),'std',('sum_of_c',np.sum)],'d':np.std,'e':lambda x:x.mean(),'e':func})
# 1. as_index 顾名思义
# 2. agg 后接一个dict,dict的key表示对这个字段进行操作,
# 3. dict 的 value 可以是字符串、函数,可以是['自定义名',字符串/函数]

常用函数

  • 内置函数(‘count’,’sum’…)
  • np函数 (np.max, np.min, np.sum, np.mean, np.median, np.std, np.std, np.size)
  • 自定义函数(func,lambda表达式)

后接自定义函数时,该自定义函数输入时每个group的每个列作为Series,返回一个数
func接受Series报错时,会尝试接受分组DataFrame,并输出一个数,或者一行数
示例:

df.groupby('w').agg(lambda dd: dd.loc[(dd.z+dd.y).idxmax()])

agg()命名

可以手动给agg后的每列命名

df.groupby('a').agg([('one','mean'),('two','std')]) # 两列不再以mean, std命名,而是改成'one', 'two'
df.groupby('a').agg({'col1':('mean_of_col1','mean'),('std_of_col1','std')]})
df.groupby('a').mean().add_prefix('mean_of_') # 批量命名

transfrom()

效果同agg(),func接受每个group的Series,如果不能接受接受Series时,会尝试接受分组DataFrame,

例如,下面用一行代码做到了分组标准化

df.groupby('w').transform(lambda s:(s-s.mean())/s.std())

filter()

func接收每个group的DataFrame,返回True/False。
filter根据返回的True/False决定是否保留这一个group

下面这段代码剔除了最大值大于0.6的组

df.groupby('w').filter(lambda s:s.x.max()<0.6)

apply()

apply用法十分灵活,可以完成上面的agg,transfrom,filter等。

def func(df,n=5,b=9):
    return 1
df.groupby('col1').apply(func,n=1,b=3) # n=1, b=3是func的输入

其它用法

creditcard_exp.groupby('gender')['avg_exp'].describe()

您的支持将鼓励我继续创作!