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

新手上路,请多包涵

我无法弄清楚 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

原文由 David D 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 985
2 个回答

apply 将函数应用于每个组(您的 Species )。您的函数返回 1,因此您最终为 3 组中的每组得到 1 个值。

agg 聚合每组的 每一列(特征) ,所以你最终每组每列有一个值。

请务必阅读 groupby 文档,它们很有帮助。网络上还流传着大量教程。

原文由 TomAugspurger 发布,翻译遵循 CC BY-SA 3.0 许可协议

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

使用 --- 与 .apply() 相比, DataFrame GroupBy 对象 的一些似是而非 .agg() 优势 是:

  1. .agg() 提供 一次应用多个函数 的灵活性,或将函数列表传递给每一列。

  2. 此外, 一次将不同的功能应用于数据框的不同列。

这意味着您几乎可以控制每个操作的每一列。

这是更多详细信息的链接:http: //pandas.pydata.org/pandas-docs/version/0.13.1/groupby.html


但是, apply 函数可以限制为一次将一个函数应用于数据帧的每一列。因此,您可能必须重复调用 apply 函数以调用对同一列的不同操作。

以下是 DataframeGroupBy 对象的 .apply().agg() 的一些示例比较:

给定以下数据框:

 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

让我们先看看使用 .apply() 的操作:

 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 [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


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

(例如: axis = 0 暗示按列操作 .apply(), 这是默认模式,而 axis = 1 暗示处理纯数据帧操作时对象)。

原文由 Surya 发布,翻译遵循 CC BY-SA 4.0 许可协议

推荐问题