3

考虑数据框:

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?

4

1 回答 1

2

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

  • 如果你通过a dictor listto apply,你会得到一个item-by-item agg,IOW,你会得到一个Series

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

  • 传递一个函数,与单字符串聚合器相同

现在是问题所在。

如果传递的函数发生故障(意味着引发 a TypeError),这意味着它将逐项执行(因此您将得到 a 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)
于 2013-06-13T23:40:37.133 回答