原创蛋壳先生 发布于2018-11-05 18:41:23 阅读数 1695 收藏
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
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
然后我们分别用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
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#使用apply
grouped.apply(sum)
data1 data2 key
key
A 3 8 AA
B 5 7 BB
C 7 12 CC
1
2
3
4
5
6
7
8
#使用agg
grouped.agg(sum)
data1 data2
key
A 3 8
B 5 7
C 7 12
1
2
3
4
5
6
7
8
#使用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
1
2
3
4
5
6
7
8
9
10
11
首先,我们很容易看出,agg的作用就是起到累积分组函数的功能,当然它还可以输入字符串、函数或者函数列表(大家可以试试下面的这些内容),在这里,apply和agg的功能是重叠的,只是apply多了一列,因为agg处理的是分组后的所有列的和,而apply处理的是分组后,传入apply的函数的DataFrame的所有列。
其次,transform和apply及agg的区别就很清楚了,它是把所有列求和的值,然后再返回原数据结构,所以返回的数据结构大小是不变的,这一点有其很特殊的地位。
grouped.agg(['min',np.median,max])
grouped.agg({'data1':'min','data2':'max'})
1
2
最后,我再来给大家演示一下,apply和agg的区别之处,apply是一个极其灵活的函数,如果要一句话总结,那就是,它总是输入分组数据的DataFrame,返回Pandas对象或者标量。而agg却只能返回分组聚合之后的标量。
我用这个例子来解释一下:
#定义一个处理分组数据的函数
def sum_transform(group):
group['sum_data1']=group.data1.sum()
group['sum_data2']=group.data2.sum()
return group
1
2
3
4
5
#然后用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
1
2
3
4
5
6
7
8
9
10
11
大家注意看一下后面两列的计算结果,是和transform的计算结果一样的,所以apply在这一点的功能上,完全和transform又是相同的,可以再去看一下上面对于apply的一句话总结,就能对apply的使用有一个更好的理解了。
总结:三个方法中,apply是最灵活的,但是对于分组数据的聚合,用agg是最方便的,对于分组转换和展开,transform是最方便的,各有所长。
————————————————
版权声明:本文为CSDN博主「蛋壳先生」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。
原文链接:
https://blog.csdn.net/weixin_42946851/article/details/83754417--
FROM 223.104.3.*