``
pandas模块给数据处理的能力给予了很大的助力,但是初学者刚开始可能会被其中分组聚合的三个方法(apply,agg和transform),弄的头晕眼花,至少我自己学习的过程中是这样的,看了网上的很多解释,觉得对于初学者理解起来还是蛮困难的,翻阅了好几本python数据分析的书籍,自己总算理解了个大概,在这里给大家讲一下这三个方法。
具体请看《Python数据科学手册》(Jake Vanderplas著)的146页哈,另外这本书强烈推荐,看过Wes McKinney著的《利用Python进行数据分析》,再看这本书,很多概念会有一种恍然大悟的感觉。
简单的说,agg,transform和apply三个方法的输入对象,都是分组后的DataFrame/Series,区别在于,他们的输出类型不一样,agg输出的是缩减后的标量(或者标量列表);transform输出的是原输入的DataFrame大小的,但是数据元素经过了转换的DataFrame;apply就很灵活了,它既可以是缩减后的标量,也可以是pandas对象(注意这里是pandas对象哦,并不仅仅是DataFrame哦)。
下面我来用一个例子解释:
#创建一个DataFrame
import pandas as pd
import numpy as np
rng=np.random.RandomState(0)
df=pd.DataFrame({'key':list('ABCABC'),'data1':range(6),'data2':rng.randint(0,10,6)})
#输出的结果是这样的
data1 data2 key
0 0 5 A
1 1 0 B
2 2 3 C
3 3 3 A
4 4 7 B
5 5 9 C
然后我们分别用apply,agg,transform三个函数去处理分组对象
#创建一个分组的迭代器
grouped=df.groupby('key')
#补充一下,如果大家想看grouped到底把原DataFrame分成什么样子了,可以试试以下代码(实际是一个含分组标签和分组DataFrame的元祖,括号使用的是元组的拆分属性)
for (key,group) in grouped:
print(key)
print(group)
Out[13]:
A
data1 data2 key
0 0 5 A
3 3 3 A
B
data1 data2 key
1 1 0 B
4 4 7 B
C
data1 data2 key
2 2 3 C
5 5 9 C
#使用apply
grouped.apply(sum)
data1 data2 key
key
A 3 8 AA
B 5 7 BB
C 7 12 CC
#使用agg
grouped.agg(sum)
data1 data2
key
A 3 8
B 5 7
C 7 12
#使用transform
grouped.transform(sum)
Out[13]:
data1 data2
0 3 8
1 5 7
2 7 12
3 3 8
4 5 7
5 7 12
首先,我们很容易看出,agg的作用就是起到累积分组函数的功能,当然它还可以输入字符串、函数或者函数列表(大家可以试试下面的这些内容),在这里,apply和agg的功能是重叠的,只是apply多了一列,因为agg处理的是分组后的所有列的和,而apply处理的是分组后,传入apply的函数的DataFrame的所有列。
其次,transform和apply及agg的区别就很清楚了,它是把所有列求和的值,然后再返回原数据结构,所以返回的数据结构大小是不变的,这一点有其很特殊的地位。
grouped.agg(['min',np.median,max])
grouped.agg({'data1':'min','data2':'max'})
最后,我再来给大家演示一下,apply和agg的区别之处,apply是一个极其灵活的函数,如果要一句话总结,那就是,它总是输入分组数据的DataFrame,返回Pandas对象或者标量。而agg却只能返回分组聚合之后的标量。
我用这个例子来解释一下:
#定义一个处理分组数据的函数
def sum_transform(group):
group['sum_data1']=group.data1.sum()
group['sum_data2']=group.data2.sum()
return group
#然后用apply应用这个函数
grouped.apply(sum_transform)
Out[21]:
data1 data2 key sum_data1 sum_data2
0 0 5 A 3 8
1 1 0 B 5 7
2 2 3 C 7 12
3 3 3 A 3 8
4 4 7 B 5 7
5 5 9 C 7 12
大家注意看一下后面两列的计算结果,是和transform的计算结果一样的,所以apply在这一点的功能上,完全和transform又是相同的,可以再去看一下上面对于apply的一句话总结,就能对apply的使用有一个更好的理解了。
总结:三个方法中,apply是最灵活的,但是对于分组数据的聚合,用agg是最方便的,对于分组转换和展开,transform是最方便的,各有所长。