我无法弄清楚Pandas .aggregate
和.apply
功能之间的区别
以下面的例子为例:我加载一个数据集,做一个groupby
,定义一个简单的函数,
用户.agg
或.apply
。
正如您所看到的,我函数中的打印语句会产生相同的输出
使用.agg
和.apply
后。结果,另一方面是不同的。那是为什么?
import pandas
import pandas as pd
iris = pd.read_csv('iris.csv')
by_species = iris.groupby('Species')
def f(x):
...: print type(x)
...: print x.head(3)
...: return 1
使用apply
:
by_species.apply(f)
#<class 'pandas.core.frame.DataFrame'>
# Sepal.Length Sepal.Width Petal.Length Petal.Width Species
#0 5.1 3.5 1.4 0.2 setosa
#1 4.9 3.0 1.4 0.2 setosa
#2 4.7 3.2 1.3 0.2 setosa
#<class 'pandas.core.frame.DataFrame'>
# Sepal.Length Sepal.Width Petal.Length Petal.Width Species
#0 5.1 3.5 1.4 0.2 setosa
#1 4.9 3.0 1.4 0.2 setosa
#2 4.7 3.2 1.3 0.2 setosa
#<class 'pandas.core.frame.DataFrame'>
# Sepal.Length Sepal.Width Petal.Length Petal.Width Species
#50 7.0 3.2 4.7 1.4 versicolor
#51 6.4 3.2 4.5 1.5 versicolor
#52 6.9 3.1 4.9 1.5 versicolor
#<class 'pandas.core.frame.DataFrame'>
# Sepal.Length Sepal.Width Petal.Length Petal.Width Species
#100 6.3 3.3 6.0 2.5 virginica
#101 5.8 2.7 5.1 1.9 virginica
#102 7.1 3.0 5.9 2.1 virginica
#Out[33]:
#Species
#setosa 1
#versicolor 1
#virginica 1
#dtype: int64
使用agg
by_species.agg(f)
#<class 'pandas.core.frame.DataFrame'>
# Sepal.Length Sepal.Width Petal.Length Petal.Width Species
#0 5.1 3.5 1.4 0.2 setosa
#1 4.9 3.0 1.4 0.2 setosa
#2 4.7 3.2 1.3 0.2 setosa
#<class 'pandas.core.frame.DataFrame'>
# Sepal.Length Sepal.Width Petal.Length Petal.Width Species
#50 7.0 3.2 4.7 1.4 versicolor
#51 6.4 3.2 4.5 1.5 versicolor
#52 6.9 3.1 4.9 1.5 versicolor
#<class 'pandas.core.frame.DataFrame'>
# Sepal.Length Sepal.Width Petal.Length Petal.Width Species
#100 6.3 3.3 6.0 2.5 virginica
#101 5.8 2.7 5.1 1.9 virginica
#102 7.1 3.0 5.9 2.1 virginica
#Out[34]:
# Sepal.Length Sepal.Width Petal.Length Petal.Width
#Species
#setosa 1 1 1 1
#versicolor 1 1 1 1
#virginica 1 1 1 1
答案 0 :(得分:26)
apply
将该功能应用于每个组(您的Species
)。你的函数返回1,所以你最终得到3组中每一组的1个值。
agg
聚合每个组的每个列(功能),因此每组每列最终会有一个值。
请阅读groupby
文档,它们非常有用。网络上还有一堆教程。
答案 1 :(得分:11)
(注意:这些比较与DataframeGroupby对象相关)
与.apply()相比,使用.agg()的一些合理的优势,对于DataFrame GroupBy对象的将是:
1).agg()提供了一次应用多个函数的灵活性,或者将函数列表传递给每一列。
2)此外,一次将不同的功能应用于不同的数据帧列。
这意味着每次操作都可以控制每列。
以下是有关详细信息的链接:http://pandas.pydata.org/pandas-docs/version/0.13.1/groupby.html
但是,apply函数可以限制为一次将一个函数应用于数据帧的每个列。因此,您可能需要重复调用apply函数来调用同一列的不同操作。
这里是针对DataframeGroupBy对象的.apply()vs .agg()的一些示例比较:
让我们首先看一下使用.apply()的操作:
In [261]: df = pd.DataFrame({"name":["Foo", "Baar", "Foo", "Baar"], "score_1":[5,10,15,10], "score_2" :[10,15,10,25], "score_3" : [10,20,30,40]})
In [262]: df
Out[262]:
name score_1 score_2 score_3
0 Foo 5 10 10
1 Baar 10 15 20
2 Foo 15 10 30
3 Baar 10 25 40
In [263]: df.groupby(["name", "score_1"])["score_2"].apply(lambda x : x.sum())
Out[263]:
name score_1
Baar 10 40
Foo 5 10
15 10
Name: score_2, dtype: int64
In [264]: df.groupby(["name", "score_1"])["score_2"].apply(lambda x : x.min())
Out[264]:
name score_1
Baar 10 15
Foo 5 10
15 10
Name: score_2, dtype: int64
In [265]: df.groupby(["name", "score_1"])["score_2"].apply(lambda x : x.mean())
Out[265]:
name score_1
Baar 10 20.0
Foo 5 10.0
15 10.0
Name: score_2, dtype: float64
现在,毫不费力地使用.agg()查看相同的操作:
In [274]: df = pd.DataFrame({"name":["Foo", "Baar", "Foo", "Baar"], "score_1":[5,10,15,10], "score_2" :[10,15,10,25], "score_3" : [10,20,30,40]})
In [275]: df
Out[275]:
name score_1 score_2 score_3
0 Foo 5 10 10
1 Baar 10 15 20
2 Foo 15 10 30
3 Baar 10 25 40
In [276]: df.groupby(["name", "score_1"]).agg({"score_3" :[np.sum, np.min, np.mean, np.max], "score_2":lambda x : x.mean()})
Out[276]:
score_2 score_3
<lambda> sum amin mean amax
name score_1
Baar 10 20 60 20 30 40
Foo 5 10 10 10 10 10
15 10 30 30 30 30
因此,与.apply()相比,.agg()在处理DataFrameGroupBy对象时非常方便。 但是,如果您只处理纯数据帧对象而不处理DataFrameGroupBy对象,则apply()非常有用,因为apply()可以沿数据框的任意轴应用函数。
(对于Eg:axis = 0表示使用.apply()的列式操作,这是默认模式, axis = 1表示在处理时按行进行操作使用纯数据帧对象)
答案 2 :(得分:0)
当使用Apply到groupby时,我遇到了.apply将返回分组的列。文档(pandas.pydata.org/pandas-docs/stable/groupby.html)中有一条注释:
“ ...因此,分组的列可能会包含在输出中并设置索引。”
.aggregate将不返回分组的列。
答案 3 :(得分:0)
apply和aggregate之间的主要区别是:
apply()-
cannot be applied to multiple groups together
For apply() - We have to get_group()
ERROR : -iris.groupby('Species').apply({'Sepal.Length':['min','max'],'Sepal.Width':['mean','min']})# It will throw error
Work Fine:-iris.groupby('Species').get_group('Setosa').apply({'Sepal.Length':['min','max'],'Sepal.Width':['mean','min']})# It will throw error
#because functions are applied to one data frame
agg()-
can be applied to multiple groups together
For apply() - We do not have to get_group()
iris.groupby('Species').agg({'Sepal.Length':['min','max'],'Sepal.Width':['mean','min']})
iris.groupby('Species').get_group('versicolor').agg({'Sepal.Length':['min','max'],'Sepal.Width':['mean','min']})