回顾
在数据处理进阶pandas入门(十六)中,我们介绍了pandas中分组方法groupby()的各种分组方式以及多计算方法agg()的基本概念与用法。今天我们讲一下对groupby()方法分组数据处理的两个方法:数据分组转换transform()方法和一般化Groupby方法apply()方法。
数据分组转换transform()方法
我们知道,DataFrame经过groupby()方法分组后可以进行函数运算,例如我们可以将一个DataFrame分组后求平均值。代码如下。
import numpy as npimport pandas as pddf = pd.DataFrame({'data1': np.random.rand(5), 'data2': np.random.rand(5), 'key1': list('aabba'), 'key2': ['one', 'two', 'one', 'two', 'one']})print(df)print("---------------")k_mean = df.groupby('key1').mean()print(k_mean)print("---------------")print(pd.merge(df, k_mean, left_on='key1', right_index=True))
上述代码中,我们将DataFrame按索引key1分组后调用mean()方法求均值,并将结果与原DataFrame聚合后生成一个新的DataFrame。运行结果如下图所示。
对于分组后的运算,除了直接在分组后调运算函数外,pandas还提供了其他方法来实现分组后的运算,transform()方法就是其中一个。transform()方法可以接收函数,对分组结果进行相应的函数操作。我们可以使用transform()方法实现上述需求。具体代码如下。
import numpy as npimport pandas as pddf = pd.DataFrame({'data1': np.random.rand(5), 'data2': np.random.rand(5), 'key1': list('aabba'), 'key2': ['one', 'two', 'one', 'two', 'one']})print(df)print("---------------")k_mean = df.groupby('key1').mean()print(k_mean)print("---------------")print(df.groupby('key1').transform(np.mean))print("---------------")k_transform = df.groupby('key1').transform(np.mean)print(pd.merge(df, k_transform, left_index=True, right_index=True))
我们将DataFrame按索引key1分组后调用transform()方法,传入求均值函数np.mean,可以得到一个和原DataFrame结构一样的DataFrame。运行结果如下图所示,可以看到,利用transfrom()方法同样可以实现分组后的计算,并且相比于分组后直接调用运算函数,transfrom()方法还能够得到与原DataFrame结构一样的DataFrame。
transform()方法还支持传入自定义函数。例如现在我们需要对分组后的结果进行去均值操作(即对每个数据进行减去均值的操作),我们可以自定义一个去均值函数,然后传入transform()方法实现需求。具体代码如下。
import numpy as npimport pandas as pddf = pd.DataFrame({'data1': np.random.rand(5), 'data2': np.random.rand(5), 'key1': list('aabba'), 'key2': ['one', 'two', 'one', 'two', 'one']})print(df)print("---------------")print(df.groupby('key1').transform(np.mean))print("---------------")func = lambda arr:arr-arr.mean()k_transform = df.groupby('key1').transform(func)print(pd.merge(df, k_transform, left_index=True, right_index=True))
运行结果如下图所示。为了便于观察,我们打印了均值结果,可以看到,data1_y和data2_y两列分组后的运算结果为去均值结果。
一般化Groupby方法apply()方法
除了transform()方法,pandas中具有类似功能的还有apply()方法。apply()方法被称为一般化groupby方法,它可以直接运行其中的函数,并将分组结果作为传入函数的参数传递给函数,然后尝试将函数的返回结果组合起来。apply()方法的基本用法如下。
import numpy as npimport pandas as pddf = pd.DataFrame({'data1': np.random.rand(5), 'data2': np.random.rand(5), 'key1': list('aabba'), 'key2': ['one', 'two', 'one', 'two', 'one']})print(df)print("---------------")print(df.groupby('key1').apply(lambda x:x.describe()))
上述代码中,我们将一个匿名函数传入apply()方法,这个匿名函数的作用是接收一个数组参数,并返回统计量。apply()方法会直接将groupby()方法的分组结果作为参数传递给这个匿名函数,从而实现对分组结果的相应处理。运行结果如下图所示。
当然,除了匿名函数,我们也可以定义一些接收多参数的复杂函数,传入apply()方法来处理分组结果。
import numpy as npimport pandas as pd# 返回排序后的前n行数据def func1(d, n): return d.sort_index()[:n]# 返回分组后表的索引为k的列,结果为Series 层次化索引def func2(d, k): return d[k]df = pd.DataFrame({'data1': np.random.rand(5), 'data2': np.random.rand(5), 'key1': list('aabba'), 'key2': ['one', 'two', 'one', 'two', 'one']})print(df)print("---------------")print(df.groupby('key1').apply(func1, 2))print("---------------")print(df.groupby('key1').apply(func2, "data2"))
上述代码中,我们定义了两个函数,功能分别为返回分组数据排序后的前n行数据、返回分组后索引为k的列数据。apply()方法的第一个参数接收函数名,后面的参数传入的则是接收函数所需的参数(apply()方法会将分组结果作为参数d直接传给func1和func2,故不需要再显示传入)。运行结果如下图所示。
总结
以上内容介绍了pandas中对groupby()方法的分组数据进行处理的两个方法,有了transform()和apply()这两个方法后,我们可以对分组数据进行各种处理。感谢大家的支持与关注,欢迎批评指正,欢迎一起交流~