Python 使用pandas GroupBy.agg()对同一列进行多个聚合

Python 使用pandas GroupBy.agg()对同一列进行多个聚合,python,pandas,dataframe,aggregate,pandas-groupby,Python,Pandas,Dataframe,Aggregate,Pandas Groupby,是否有一种内置方法可以将两个不同的聚合函数f1、f2应用于同一列df[“returns”],而无需多次调用agg() 数据帧示例: import pandas as pd import datetime as dt import numpy as np pd.np.random.seed(0) df = pd.DataFrame({ "date" : [dt.date(2012, x, 1) for x in range(1, 11)],

是否有一种内置方法可以将两个不同的聚合函数
f1、f2
应用于同一列
df[“returns”]
,而无需多次调用
agg()

数据帧示例:

import pandas as pd
import datetime as dt
import numpy as np

pd.np.random.seed(0)
df = pd.DataFrame({
         "date"    :  [dt.date(2012, x, 1) for x in range(1, 11)], 
         "returns" :  0.05 * np.random.randn(10), 
         "dummy"   :  np.repeat(1, 10)
}) 
语法上错误,但直觉上正确的做法是:

# Assume `f1` and `f2` are defined for aggregating.
df.groupby("dummy").agg({"returns": f1, "returns": f2})
显然,Python不允许重复键。是否有其他方式来表达对
agg()
的输入?也许元组列表
[(列,函数)]
可以更好地工作,允许对同一列应用多个函数?但是
agg()
似乎只接受字典


除了定义一个只应用其中两个函数的辅助函数外,还有其他解决方法吗?(无论如何,聚合是如何工作的?

是否有类似的工作:

In [7]: df.groupby('dummy').returns.agg({'func1' : lambda x: x.sum(), 'func2' : lambda x: x.prod()})
Out[7]: 
              func2     func1
dummy                        
1     -4.263768e-16 -0.188565

您只需将函数作为列表传递:

In [20]: df.groupby("dummy").agg({"returns": [np.mean, np.sum]})
Out[20]:         
           mean       sum
dummy                    
1      0.036901  0.369012
或作为字典:

In [21]: df.groupby('dummy').agg({'returns':
                                  {'Mean': np.mean, 'Sum': np.sum}})
Out[21]: 
        returns          
           Mean       Sum
dummy                    
1      0.036901  0.369012

TLDR;Pandas
groupby.agg
有一个新的、更简单的语法,用于指定(1)多个列上的聚合,以及(2)一个列上的多个聚合。因此,要对熊猫>=0.25执行此操作,请使用

df.groupby('dummy').agg(Mean=('returns', 'mean'), Sum=('returns', 'sum'))

           Mean       Sum
dummy                    
1      0.036901  0.369012


熊猫>=0.25: Pandas已经改变了
GroupBy.agg
的行为,支持使用更直观的语法来指定命名聚合。请参阅以及相关的GitHub问题和

根据文件

支持特定于列的聚合并控制输出 列名,熊猫接受
GroupBy.agg()中的特殊语法,
称为“命名聚合”,其中

  • 关键字是输出列名
  • 值是元组,其第一个元素是要选择的列,第二个元素是要应用于该列的聚合。 Pandas提供Pandas.namedag namedtuple和字段 ['column','aggfunc']来更清楚地说明参数是什么。作为 通常,聚合可以是可调用的别名或字符串别名
现在可以通过关键字参数传递元组。元组的格式为
(,在较新版本的pandas上,可以更简单地通过传递元组列表来指定。如果以这种方式指定函数,则该列的所有函数都需要指定为(名称、函数)对的元组

或者



不,这不起作用。如果您查看
聚合的文档字符串,它明确表示当传递
dict
时,键必须是列名。因此,要么您的示例是您在未检查此错误的情况下键入的,要么Panda在此处破坏了自己的文档。N/M我没有看到对
的额外调用返回
在那里。这是聚合的系列版本吗?我想做聚合的数据帧版本,我想同时对每个列应用几个不同的聚合。试试这个:df.groupby('dummy').agg({'returns':{'func1':lambda x:x.sum(),'func2':lambda x:x.mean()})它给出了一个没有消息的断言错误看起来它在最后进行了检查,以确保返回的列数不会超过聚合字典第一层中的键数。在master上运行良好。是否尝试更新?是否有方法指定结果列名?@Ben我想您必须在以后使用重命名。@Ben:我添加了一个example@sparc_spread经过列表形式的多个函数。在pandas的未来版本中,将不推荐将多个函数重命名为字典并将其传递为字典。详细信息见,我也这么说。已经说过,但不推荐使用字典从年代开始重命名输出列。您可以改为指定元组列表。相关-从0.25开始,pandas为多个聚合以及重命名输出列提供了更直观的语法。请参阅上的文档。仅供参考,此问题早在2012年9月pandas 0.8.x上就被问到了。接受的答案也被弃用-不要传递agg()一个dict of dicts@cs95:我知道它已经被弃用了,我是说它已经被旧版本的陈旧解决方案弄得乱七八糟了。所以除了注释之外,没有其他方法来标记它。这应该是最重要的答案,因为使用了更新版本的接口使用了更清晰的解决方案。用于命名聚合的示例确实如此esn无法解决在同一列上使用多个聚合的原始问题。例如,您是否可以按高度的最小值和最大值进行聚合,而无需对
df.groupby('kind')['height'进行第一个子集设置
?@victor我在答案的顶部添加了一个TLDR,直接解决了这个问题。第二个问题的答案是肯定的,请查看我答案的编辑。在你的>=0.25答案的最后一个示例中,使用一个更通用的代码来处理像这样聚合多个列的问题会更好。
df.groupby(“kind”).agg(**{'max height':pd.namedagh(column='height',aggfunc=max),'min weight':pd.namedagh(column='weight',aggfunc=min)})
回答得很好!如何使用lambda函数实现这一点?
df.groupby('dummy')['returns'].agg(Mean='mean', Sum='sum')

           Mean       Sum
dummy                    
1      0.036901  0.369012
import pandas as pd

pd.__version__                                                                                                                            
# '0.25.0.dev0+840.g989f912ee'

# Setup
df = pd.DataFrame({'kind': ['cat', 'dog', 'cat', 'dog'],
                   'height': [9.1, 6.0, 9.5, 34.0],
                   'weight': [7.9, 7.5, 9.9, 198.0]
})

df.groupby('kind').agg(
    max_height=('height', 'max'), min_weight=('weight', 'min'),)

      max_height  min_weight
kind                        
cat          9.5         7.9
dog         34.0         7.5
df.groupby('kind').agg(
    max_height=pd.NamedAgg(column='height', aggfunc='max'), 
    min_weight=pd.NamedAgg(column='weight', aggfunc='min')
)

      max_height  min_weight
kind                        
cat          9.5         7.9
dog         34.0         7.5
df.groupby('kind')['height'].agg(max_height='max', min_height='min')    

      max_height  min_height
kind                        
cat          9.5         9.1
dog         34.0         6.0       
df.groupby('kind')['height'].agg(**{'max height': 'max', ...})
df.groupby('dummy').agg({'returns': {'Mean': 'mean', 'Sum': 'sum'}})
# FutureWarning: using a dict with renaming is deprecated and will be removed 
# in a future version
df.groupby("dummy").agg({'returns': [('op1', 'sum'), ('op2', 'mean')]})

        returns          
            op1       op2
dummy                    
1      0.328953  0.032895
df.groupby("dummy")['returns'].agg([('op1', 'sum'), ('op2', 'mean')])

            op1       op2
dummy                    
1      0.328953  0.032895