
4.3 数据分组统计
本节主要介绍分组统计函数groupby()的各种应用。
4.3.1 分组统计groupby()函数
对数据进行分组统计,主要使用DataFrame对象的groupby()函数,其功能如下。
(1)根据给定的条件将数据拆分成组。
(2)每个组都可以独立应用函数(如求和函数sum()、求平均值函数mean()等)。
(3)将结果合并到一个数据结构中。
groupby()函数用于将数据按照一列或多列进行分组,一般与计算函数结合使用,实现数据的分组统计,语法如下:
DataFrame.groupby(by=None,axis=0,level=None,as_index=True,sort=True,group_keys=True,squeeze=False, observed=False)
参数说明:
by:映射、字典或Series对象、数组、标签或标签列表。如果by是一个函数,则对象索引的每个值都调用它;如果传递了一个字典或Series对象,则使用该字典或Series对象值来确定组;如果传递了数组ndarray,则按原样使用这些值来确定组。
axis:axis=1表示行,axis=0表示列。默认值为0。
level:表示索引层级,默认值为None(无)。
as_index:布尔型,默认值为True,返回以组标签为索引的对象。
sort:对组进行排序,布尔型,默认值为True。
group_keys:布尔型,默认值为True,调用apply()函数时,将分组的键添加到索引以标识片段。
squeeze:布尔型,默认值为False。如果可能,减少返回类型的维度;否则返回一致类型。
observed:当以石斑鱼为分类时,才会使用该参数。如果参数值为True,则仅显示分类石斑鱼的观测值;如果参数值为False,则显示分类石斑鱼的所有值。
返回值:返回DataFrameGroupBy,返回包含有关组的信息的groupby对象。
1.按照一列分组统计
【示例15】 根据“一级分类”统计订单数据。(示例位置:资源包\MR\Code\04\15)
按照图书“一级分类”对订单数据进行分组统计求和,程序代码如下:

运行程序,输出结果如图4.10所示。

图4.10 按照一列分组统计
2.按照多列分组统计
多列分组统计,以列表形式指定列。
【示例16】 根据两级分类统计订单数据。(示例位置:资源包\MR\Code\04\16)
按照图书“一级分类”和“二级分类”对订单数据进行分组统计求和,主要代码如下:
01 #抽取数据 02 df1=df[['一级分类','二级分类','7天点击量','订单预定']] 03 df1=df1.groupby(['一级分类','二级分类']).sum() #分组统计求和
运行程序,输出结果如图4.11所示。
3.分组并按指定列进行数据计算
前面介绍的分组统计是按照所有列进行汇总计算的,那么如何按照指定列汇总计算呢?
【示例17】 统计各编程语言的7天点击量。(示例位置:资源包\MR\Code\04\17)
统计各编程语言的7天点击量,首先按“二级分类”分组,然后抽取“7天点击量”列并对该列进行求和运算,主要代码如下:
df1=df1.groupby('二级分类')['7天点击量'].sum()
运行程序,输出结果如图4.12所示。

图4.11 按照多列分组统计

图4.12 分组并按指定列进行数据计算
4.3.2 对分组数据进行迭代
通过for循环对分组统计数据进行迭代(遍历分组数据)。
【示例18】 迭代一级分类的订单数据。(示例位置:资源包\MR\Code\04\18)
按照“一级分类”分组,并输出每一分类中的订单数据,主要代码如下:

运行程序,控制台输出结果如图4.13所示。
上述代码中,name是groupby()函数中“一级分类”的值,group是分组后的数据。如果groupby()函数对多列进行分组,那么需要在for循环中指定多列。
【示例19】 迭代两级分类的订单数据。(示例位置:资源包\MR\Code\04\19)
迭代“一级分类”和“二级分类”的订单数据,主要代码如下:


图4.13 对分组数据进行迭代
4.3.3 对分组的某列或多列使用聚合函数(agg()函数)
Python也可以实现像SQL中的分组聚合运算操作,主要通过groupby()函数与agg()函数实现。
【示例20】 对分组统计结果使用聚合函数。(示例位置:资源包\MR\Code\04\20)
按“一级分类”分组统计“7天点击量”“订单预定”的平均值和总和,主要代码如下:
print(df1.groupby('一级分类').agg(['mean','sum']))
运行程序,控制台输出结果如图4.14所示。

图4.14 分组统计“7天点击量”“订单预定”的平均值和总和
【示例21】 针对不同的列使用不同的聚合函数。(示例位置:资源包\MR\Code\04\21)
在上述示例中,还可以针对不同的列使用不同的聚合函数。例如,按“一级分类”分组统计“7天点击量”的平均值和总和、“订单预定”的总和,主要代码如下:
print(df1.groupby('一级分类').agg({'7天点击量':['mean','sum'], '订单预定':['sum']}))
运行程序,控制台输出结果如图4.15所示。

图4.15 分组统计“7天点击量”的平均值和总和、“订单预定”的总和
【示例22】 通过自定义函数实现分组统计。(示例位置:资源包\MR\Code\04\22)
通过自定义函数也可以实现数据分组统计。例如,统计1月份销售数据中,购买次数最多的产品,主要代码如下:

运行程序,控制台输出结果如图4.16所示。

图4.16 统计购买次数最多的产品
从运行结果得知:“零基础学Python”是用户购买次数最多的产品。
实用技巧
在图4.16显示的输出结果中可以看到,lambda()函数名称<lambda>被输出出来,看上去不是很美观,那么如何去掉它?方法是使用__name__方法修改函数名称,主要代码如下:
max.__name__ = "购买次数最多"
运行程序,控制台输出结果如图4.17所示。

图4.17 使用__name__方法修改函数名称
4.3.4 通过字典和Series对象进行分组统计
1.通过字典进行分组统计
首先创建字典建立对应关系,然后将字典传递给groupby()函数从而实现数据分组统计。
【示例23】 通过字典分组统计“北上广”销量。(示例位置:资源包\MR\Code\04\23)
统计各地区销量,业务要求将“北京”“上海”“广州”3个一线城市放在一起统计。那么首先创建一个字典将“北京出库销量”“上海出库销量”“广州出库销量”都对应“北上广”;然后使用groupby()函数进行分组统计。主要代码如下:

运行程序,控制台输出结果如图4.18所示。

图4.18 通过字典进行分组统计
2.通过Series对象进行分组统计
通过Series对象进行分组统计与字典的方法类似。
【示例24】 通过Series对象分组统计“北上广”销量。(示例位置:资源包\MR\Code\04\24)
首先,创建一个Series对象,主要代码如下:

运行程序,输出结果如图4.19所示。
然后,将Series对象传递给groupby()函数实现数据分组统计,主要代码如下:
01 df1=df.groupby(s1,axis=1).sum() 02 print(df1)
运行程序,控制台输出结果如图4.20所示。

图4.19 通过Series对象进行分组统计

图4.20 分组统计结果