pandas之groupby函数
sql中的分组语句group by很重要,pandas中也有类似的分组函数,即groupby,本文就主要介绍下它的用法。
一、简介
sql中的分组语句group by很重要,pandas中也有类似的分组函数,即groupby,本文就主要介绍下它的用法。
二、groupby函数
和sql中的分组类似,pandas中的groupby函数也是先将df按照某个字段进行拆分,将相同属性分为一组;然后对拆分后的各组执行相应的转换操作;最后输出汇总转换后的各组结果
2.1 分组
首先要对一个df进行分组,即进行groupby函数,其参数如下:
df.groupby(
by=None,
axis=0,
level=None,
as_index: 'bool' = True,
sort: 'bool' = True,
group_keys: 'bool' = True,
squeeze: 'bool' = <object object at 0x137ac9240>,
observed: 'bool' = False,
dropna: 'bool' = True,
)
其中,通过by
指定要分组的字段,即根据哪个字段进行分组,可以是一个,也可以是多个;axis=0
则是默认对列的值的属性进行分组,当然,也可以设为1,根据行的值的属性进行分组;as_index=True
则是默认将分组列名作为输出的索引,如果想要将其作为一个字段添加到df中,可以用reset_index方法,具体见Python pandas基础——常用属性、方法和函数。
现创建一个DataFrame作为示例(创建方法见Python pandas基础——创建Series、DataFrame):
data = {'name': ['apolo', 'apolo', 'apolo', 'adm', 'adm', 'adm', 'bolon', 'bolon', 'bolon',
'ali', 'ali', 'ali', 'cathy', 'cathy', 'cathy', 'jack', 'jack', 'jack'],
'subjects': ['math', 'english', 'chinese', 'math', 'english', 'chinese', 'math', 'english', 'chinese',
'math', 'english', 'chinese', 'math', 'english', 'chinese', 'math', 'english', 'chinese'],
'grades' : [89, 78, 84, 89, 83, 85, 77, 88, 79, 89, 86, 83, 95, 90, 94, 78, 70, 80]
}
df = pd.DataFrame(data)
df
输出:df记录了六名学生在math,English和Chinese上的考试成绩
name subjects grades
0 apolo math 89
1 apolo english 78
2 apolo chinese 84
3 adm math 89
4 adm english 83
5 adm chinese 85
6 bolon math 77
7 bolon english 88
8 bolon chinese 79
9 ali math 89
10 ali english 86
11 ali chinese 83
12 cathy math 95
13 cathy english 90
14 cathy chinese 94
15 jack math 78
16 jack english 70
17 jack chinese 80
进行分组
df.groupby('name')
输出:输出的是一个DataFrameGroupBy对象,后续的操作都是对这个DataFrameGroupBy对象进行。
<pandas.core.groupby.generic.DataFrameGroupBy object at 0x165c0b1c0>
2.2 常用的操作函数
在得到DataFrameGroupBy对象后,我们就可以根据需要进行相应的转换操作。
2.2.1 直接加聚合函数
可以在DataFrameGroupBy对象后直接加mean(), sum(), min(), max()之类的聚合函数进行相应的操作。
求平均成绩:
df.groupby('name').mean()
输出:可以看到输出了每个学生的平均成绩,结果是一个DataFrame,列索引是grades,行索引是学生的名字,name是行索引的名字。
grades
name
adm 85.666667
ali 86.000000
apolo 83.666667
bolon 81.333333
cathy 93.000000
jack 76.000000
2.2.2 agg()
agg()的功能更加强大,除了可以向agg()函数中传入聚合函数外,也常用列表、字典等形式作为参数。
传入聚合函数:
df.groupby('name').agg('mean')
输出:和直接加聚合函数的结果是一样的,但要注意的是,传入的是字符串,并不是真正的聚合函数。
grades
name
adm 85.666667
ali 86.000000
apolo 83.666667
bolon 81.333333
cathy 93.000000
jack 76.000000
传入列表:求每个学生的平均成绩和最低成绩
df.groupby('name').agg(['mean', 'min'])
输出:结果是一个多索引的DataFrame,df.groupby('name').agg(['mean', 'min'])['grade']
则是一个普通的DataFrame
grades
mean min
name
adm 85.666667 83
ali 86.000000 83
apolo 83.666667 78
bolon 81.333333 77
cathy 93.000000 90
jack 76.000000 70
2.2.3 apply()
apply()可以传入自定义的面向分组的函数。
求每个学生的数学平均成绩与英语平均成绩之差:
df.groupby('name').apply(lambda x:x[x['subjects'] == 'math']['grades'].mean() - x[x['subjects'] == 'english']['grades'].mean())
输出:输出结果是一个Series
name
adm 6.0
ali 3.0
apolo 11.0
bolon -11.0
cathy 5.0
jack 8.0
dtype: float64
2.2.4 transform
transform调用函数在每个分组上产生一个与原df相同索引的DataFrame,整体返回与原来对象拥有相同索引且已填充了转换后的值的DataFrame,相当于就是给原来的Dataframe添加了一列。
transform与agg和apply的区别相当于SQL中窗口函数和分组聚合的区别:transform并不对数据进行聚合输出,而只是对每一行记录提供了相应聚合结果;而后两者则是聚合后的分组输出。
df.groupby('name').transform('mean')
输出:结果是每个学生的平均成绩
grades
0 83.666667
1 83.666667
2 83.666667
3 85.666667
4 85.666667
5 85.666667
6 81.333333
7 81.333333
8 81.333333
9 86.000000
10 86.000000
11 86.000000
12 93.000000
13 93.000000
14 93.000000
15 76.000000
16 76.000000
17 76.000000
更多推荐
所有评论(0)