【pandas groupby()函数使用及参数详解】


1. 简述

1.1 定义

pandas中的groupby函数是先将df按照某个字段进行拆分,将相同属性分为一组;然后对拆分后的各组执行相应的转换操作;最后输出汇总转换后的各组结果

DataFrame.groupby(by=None, 
				axis=0, 
				level=None, 
				as_index=True, 
				sort=True, 
				group_keys=True, 
				squeeze=NoDefault.no_default, 
				observed=False, 
				dropna=True)

1.2 参数详解

  • by:用于确定 groupby 的组。 如果 by 是一个函数,它会在对象索引的每个值上调用。 如果传递了 dict 或 Series,则 Seriesdict VALUES 将用于确定组(Series 的值首先对齐;参见 .align() 方法)。 如果传递了长度等于所选轴的列表或 ndarray,则按原样使用这些值来确定组。 一个标签或标签列表可以通过 self 中的列传递给 group。 请注意,元组被解释为(单个)键。
  • axis:沿行 (0) 或列 (1) 拆分。
  • level:如果轴是MultiIndex(层次化),则按一个或多个特定级别进行分组。
  • as_index:对于聚合输出,返回具有组标签作为索引的对象。仅与DataFrame输入相关。as index=False是有效的sql风格的分组输出。
  • sort:对组键进行排序。 关闭此功能可获得更好的性能。 请注意,这不会影响每组内的观察顺序。 Groupby 保留每个组内的行顺序。
  • group_keys:当调用apply时,将组键添加到index以识别片段。
  • squeeze:如果可能,降低返回类型的维数,否则返回一致的类型。
  • observed:这仅适用于任何 groupers 是分类的。 如果为真:仅显示分类分组的观察值。 如果为 False:显示分类分组的所有值
  • dropna:如果为 True,并且组键包含 NA 值,则 NA 值连同行/列将被删除。 如果为 FalseNA 值也将被视为组中的键。

2. 案例

def group_by():
    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)
    print(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

进行分组

print(df.groupby('name'))

这里返回的结果是一个DataFrameGroupBy对象,后续的操作都是对这个DataFrameGroupBy对象进行

<pandas.core.groupby.generic.DataFrameGroupBy object at 0x000002DB778B6320>

2.1 基于groupby()常用的操作函数

在得到DataFrameGroupBy对象后,我们就可以根据需要进行相应的转换操作。

2.1.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

大家可以再自己试一试sum(), min(), max()方法

2.1.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'])

输出:结果是一个多索引的DataFramedf.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.1.3 apply()方法

apply()可以传入自定义的面向分组的函数。

求每个学生的数学平均成绩与英语平均成绩之差:

# 自定义函数 lambda表达式
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

3.1.4 transform()方法

transform调用函数在每个分组上产生一个与原df相同索引的DataFrame,整体返回与原来对象拥有相同索引且已填充了转换后的值的DataFrame,相当于就是给原来的Dataframe添加了一列

transformaggapply的区别相当于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

主要参考了文章:https://blog.csdn.net/TSzero/article/details/115430661


  • 15
    点赞
  • 37
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值