pandas agg和apply函数有什么区别?

Dav*_*d D 28 python pandas pandas-groupby

我无法弄清楚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
Run Code Online (Sandbox Code Playgroud)

使用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
Run Code Online (Sandbox Code Playgroud)

运用 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
Run Code Online (Sandbox Code Playgroud)

Tom*_*ger 28

apply将功能应用于每个组(您的Species).您的函数返回1,因此您最终为3个组中的每个组分配1个值.

agg聚合每个组的每个列(功能),因此每组最多每列一个值.

阅读groupby文档,他们非常有帮助.网络上还有一堆教程.

  • 因此,如果我想在整个组中使用我的`func`,我应该选择`apply`,并且如果每个组中只有一个`column`,那么agg是一个更好的选择。 (2认同)

Sur*_*rya 13

(注意:这些比较与DataframeGroupby对象相关)

使用.agg().apply()相比,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
Run Code Online (Sandbox Code Playgroud)

现在,使用.agg()毫不费力地查看相同的操作:

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
Run Code Online (Sandbox Code Playgroud)

因此,与.apply()相比,.agg()在处理DataFrameGroupBy对象时非常方便.但是,如果您只处理纯数据帧对象而不处理DataFrameGroupBy对象,则apply()非常有用,因为apply()可以沿数据帧的任意轴应用函数.

(对于Eg:axis = 0表示使用.apply()进行逐列操作,这是默认模式,而axis = 1表示在处理纯数据帧对象时进行逐行操作)