当前位置: 首页 > 知识库问答 >
问题:

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

百里鸿祯
2023-03-14

是否有一种内置方法可以将两个不同的聚合函数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()似乎只接受字典。

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

共有3个答案

东郭远航
2023-03-14

像这样的东西会起作用吗:

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
程鸿波
2023-03-14

太长,读不下去了Pandasgroupby.agg有一个新的、更简单的语法,用于指定(1)多个列上的聚合,以及(2)一个列上的多个聚合。所以,为熊猫做这件事

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

           Mean       Sum
dummy                    
1      0.036901  0.369012

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

           Mean       Sum
dummy                    
1      0.036901  0.369012

Pandas已经改变了GroupBy.agg的行为,支持使用更直观的语法来指定命名聚合。请参阅0.25文档中关于增强功能以及相关GitHub问题GH18366和GH26512的部分。

根据文件,

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

  • 关键字是输出列名
  • 值是元组,其第一个元素是要选择的列,第二个元素是要应用于该列的聚合。Pandas为Pandas.namedag namedtuple提供了字段['column','aggfunc'],以便更清楚地说明参数是什么。通常,聚合可以是可调用的别名或字符串别名

现在可以通过关键字参数传递元组。元组的格式为(

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

或者,您可以使用pd.namedagh(本质上是一个namedtuple),这使得事情更加明确。

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

对于Series更简单,只需将aggfunc传递给关键字参数即可。

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       

最后,如果您的列名不是有效的python标识符,请使用解压字典:

df.groupby('kind')['height'].agg(**{'max height': 'max', ...})

在高达0.24的pandas的最新版本中,如果使用字典指定聚合输出的列名,您将得到一个FutureWarning

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

在v0.20中不建议使用字典重命名列。在熊猫的最新版本中,可以通过传递元组列表来更简单地指定。如果以这种方式指定函数,该列的所有函数都需要指定为(名称、函数)对的元组。

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

微生高谊
2023-03-14

您可以简单地将函数作为列表传递:

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
 类似资料:
  • 问题内容: 好的,我想我可能会忽略一些显而易见的/简单的事情…但是我需要编写一个查询,该查询仅返回与同一列上的多个条件匹配的记录… 我的表是一个非常简单的链接设置,用于将标志应用于用户… 等等…在这种情况下,您会看到联系人99和100都被标记为“志愿者”和“已上传” … 我需要做的是返回仅与通过搜索表单输入的多个条件相匹配的那些contactid … contactid必须与所有选择的标志匹配…在

  • 好吧,我想我可能忽略了一些明显的/简单的事情...但我需要编写一个查询,该查询只返回同一列上符合多个条件的记录... 我的表是一个非常简单的链接设置,用于向用户应用标志... 等等。在这种情况下,您将看到联系人99和100都被标记为“志愿”和“上载”。 我需要能够做的是返回那些联系人ID只匹配通过搜索表单输入的多个条件...联系人ID必须匹配所有选择的标志...在我看来,SQL应该类似于: 但是.

  • 我有两个不同的表,Person表和Employee表。我需要这两者之间的一一对应。Employee表的emp_id引用Person表的PERSON_ID。我需要一些帮助来编写使用注释的映射 persons.java

  • 本文向大家介绍使用MongoDB聚合按多个字段进行计数,包括了使用MongoDB聚合按多个字段进行计数的使用技巧和注意事项,需要的朋友参考一下 要按多个字段计数,请在MongoDB中使用$facet。在$facet处理在同一组输入文档的单级中的多个聚集的管道。让我们创建一个包含文档的集合- 在find()方法的帮助下显示集合中的所有文档- 这将产生以下输出- 以下是要按多个字段计数的查询- 这将产

  • 我知道已经有很多相关的问题了,但是没有一个回答了我的特殊需求。 我想在一个有50列的表上使用dplyr“summary”,我需要对这些列应用不同的摘要函数。 “SUMMARE_all”和“SUMMARY_at”似乎都有缺点,即不可能将不同的函数应用于变量的不同子组。 例如,让我们假设iris数据集有50列,所以我们不想按名称寻址列。我需要前两列的总和、第三列的平均值以及所有剩余列的第一个值(在gr

  • 问题内容: 我有3列让说,和。我需要计算每列中的值。 例如: 应该输出: 我已经尝试了数,总和,子查询,但是还没有任何工作适合我。任何输入将不胜感激! 问题答案: