Python大数据与机器学习实战
上QQ阅读APP看本书,新人免费读10天
设备和账号都新为新人

3.3 分组运算

分组运算(Groupby)是指按某一特征(字段)将一个大数据表分成几张小表,分表后经过统计处理再将结果重组。分组操作极大地简化了数据处理的流程,并提高了处理效率。

3.3.1 分组

本小节先从一个实例开始,实例使用1996年美国大选的数据集。首先载入数据集,并查看数据的基本情况。

数据基本情况如表3.2所示,可以看到表中多数列为类别(枚举)类型。

表3.2 美国大选数据集前五行数据

分组既可以对Series分组,也可以对DataFrame分组,支持使用一个特征及多个特征作为分组条件。当使用“受教育程度”分组时,数据被分为七组,每种受教育程度相同的记录被分成一组;按“受教育程度”和“投票”两个特征分组时,数据表被分成14个组,每种特征的组合分为一组。另外,还可以使用lambda表达式作为分组依据。下例中按索引值奇偶将数据分成两组。

执行groupby命令后数据并未被真正拆分,只是在访问组中的数据时才会执行拆分操作,这会使得分组操作变得快速且节约存储空间。

使用get_group方法可获取某一组中的所有记录。

一般通过迭代方式访问分组元素,其中desc为分组的特征值,item是包含该组中的所有记录的新数据表。

使用字段名作为下标可获得只包含该字段的新组,用这种方式可实现依据某一列给另一列分组,以供后续计算。下例中按vote分组后取每组的age,迭代方式访问的元素item是Series类型,其中包含该组中的所有age值。

统计分组后的数据也是常用的操作,如统计为不同候选人投票的两组的人数和平均年龄,方法如下例所示。除了计数和求平均值,也可以使用求和、求中值等其他统计方法。

上例中返回值的类型为Series,分组变量的取值为索引值,组中元素个数为value。还可以利用reset_index方法将结果转换成单层索引的DataFrame,其中分组变量vote和年龄均值age都已转换成新数据表中的字段。

3.3.2 聚合

聚合(Agg)可以对每组中的数据进行聚合运算,即把多个值按指定方式转换成一个值。Agg的参数是处理函数,它将列中的数据转给处理函数,为方便理解,还是从实例开始。本例中使用statsmodels中自带的信用卡数据,数据非常简单,只有五个字段。

使用OWNRENT值分组,由于它的取值为0或1,因此数据被分为两组,用集合方法调用取平均值的函数来聚合数据。

返回结果也是DataFrame对象。转换后的字段和原表相同,记录变为两个,分别对应不同的分组,表中的数据是该字段不同组的均值。本例中使用了Numpy的均值函数,也可用自定义函数,或者使用lambda表达式定义处理方法,如下例中将每组中收入最高的记录作为变换后的值。

3.3.3 转换

转换(Transform)是将数据表中的每个元素按不同组进行不同的转换处理,转换之后的行索引和列索引不变,只有内容改变。下例中将收入(INCOME)的实际值转换为INCOME减去该组的均值,用于表示其收入在所属组中是偏高还是偏低。

聚合和转换都支持将DataFrame和Series作为输入。上例中将DataFrame作为处理对象,输出的是DataFrame;本例中将Series作为处理对象,转换后输出的也是Series。

3.3.4 过滤

过滤(Filter)是通过一定的条件从原数据表中过滤掉一些数据,过滤之后列不变,行可能减少,具体方法是按组过滤,即过滤掉某些组。

本例中,使用lambda函数过滤掉了收入(INCOME)均值小于3的组。

处理函数接收的参数是某一分组中的所有数据,返回布尔值。当布尔值为True时保留该组,当布尔值为False时过滤掉该组,判断条件一般是根据组中数据求出的统计值。

3.3.5 应用

相对于前几种方法,应用(Apply)更加灵活,并且能实现前几种处理的功能。其处理函数的输入是各组的DataFrame,返回值可以是数值、Series,DataFrame,apply会根据返回的不同类型构造不同的输出结构。

用apply实现聚合功能:

用apply实现转换功能:

用apply实现过滤功能与使用filter函数不同的是,当满足条件时,返回df;当不满足条件时,返回None,即在重组时忽略该返回值。

除以上功能外,apply还提供更灵活的使用方式,比如返回符合条件组中的前N条。

Pandas对常用的聚合功能在底层做了优化,使apply函数的速度比自行分组计算之后再组合快得多,因此其是数据处理中不可或缺的工具。