【问题标题】:When does df.groupby(...).agg(myagg) pass a Series to myagg?df.groupby(...).agg(myagg) 何时将 Series 传递给 myagg?
【发布时间】:2013-06-15 01:46:15
【问题描述】:

考虑 DataFrame:

import pandas as pd
df = pd.DataFrame({'A':[1,2,1,2],
                   'B':[1,2,1,2],
                   'C':list('WXYZ'),
                   'D':list('abcd')})
df.set_index('A', inplace=True)
print(df)
#    B  C  D
# A         
# 1  1  W  a
# 2  2  X  b
# 1  1  Y  c
# 2  2  Z  d

def myagg(x):
    print(type(x).__name__)
    print(x)

通常,df.groupby(...).agg(myagg) 会将(子)DataFrames 传递给 myagg。例如,

df.groupby(level=0).agg(myagg)
# DataFrame
#    B  C  D
# A         
# 1  1  W  a
# 1  1  Y  c
# DataFrame
#    B  C  D
# A         
# 2  2  X  b
# 2  2  Z  d

但是,如果您使用多级索引,则 myagg 将传递一个系列:

df2 = df.set_index(['B'], append=True)
df2.groupby(level=['A','B']).agg(myagg)
# Series
# A  B
# 1  1    W
#    1    Y
# Name: C
# Series
# A  B
# 2  2    X
#    2    Z
# Name: C
# Series
# A  B
# 1  1    a
#    1    c
# Name: D
# Series
# A  B
# 2  2    b
#    2    d
# Name: D

有时这可能非常有用,但我想更好地理解 agg 何时将单列(系列)传递给myagg,何时通过 整个 DataFrame?

【问题讨论】:

  • 我觉得第一个是不正确的行为。就像流行的说法:“编写聚合函数很难……让我们去编写应用函数吧。”

标签: pandas


【解决方案1】:

可能需要遍历所有案例,但这里有一些经验法则(假设在 DataFrame 上分组):

  • 如果你通过dictlist 申请,你将获得逐项聚合,IOW,你将获得Series

  • 作为字符串传递的单个聚合器(例如 mean,sum)将作为 DataFrame(实际上你会在不同的 dtyped 块上被多次调用)

  • 传递一个函数,和单字符串聚合器一样

现在是问题所在。

如果传递的函数发生故障(意味着引发TypeError),这意味着它将逐项执行(因此您将获得Series

我相信,如果有一个单独的组,您会收到 DataFrame,但如果出现问题,您将再次退回到逐项。

回答 unutbu 问题:

当有多个键时(例如第二个示例),默认是与具有多索引的系列聚合,而单个键将进行数据帧聚合(取决于我上面的问题)

pandas/core/groupby.py 中的起始行 1745

   if self.grouper.nkeys > 1:
        return self._python_agg_general(arg, *args, **kwargs)
    else:
        result = self._aggregate_generic(arg, *args, **kwargs)

【讨论】:

  • builtins 也被 Cythonized...(因此,如果您通过 .agg(sum),如果您使用 .agg('sum'),它会将其转换为相同)[至少在 dev 分支上]跨度>
  • 你能指出源代码中的什么原因导致groupby(level=0).agg(myagg) 用DataFrames 调用myagg,但groupby(level=['A','B']).agg(myagg) 用Series 调用myagg
猜你喜欢
  • 2013-02-25
  • 2018-09-07
  • 2013-07-08
  • 1970-01-01
  • 2017-11-18
  • 2019-11-10
  • 1970-01-01
  • 1970-01-01
  • 2014-12-08
相关资源
最近更新 更多