【问题标题】:python pandas: applying different aggregate functions to different columnspython pandas:将不同的聚合函数应用于不同的列
【发布时间】:2019-07-23 02:32:15
【问题描述】:

我试图理解这个简单的 SQL 语句的等价物是什么:

select mykey, sum(Field1) as sum_of_field1, avg(Field1) as avg_field1, min(field2) as min_field2
from df
group by mykey

我知道我可以将字典传递给 agg() 函数:

  f = {'Field1':'sum',
         'Field2':['max','mean'],
         'Field3':['min','mean','count'],
         'Field4':'count'
         }

    grouped = df.groupby('mykey').agg(f)

但是,生成的列名似乎是由 pandas 自动选择的:('Field1','sum') 等。

有没有办法为列名传递字符串,这样该字段就不是('Field1','sum'),而是我可以选择的东西,比如 sum_of_field1 ?

谢谢。我在这里查看了文档:http://pandas.pydata.org/pandas-docs/stable/groupby.html 但找不到答案。

【问题讨论】:

    标签: python pandas dataframe


    【解决方案1】:

    从 pandas 0.25 开始,这可以通过 "Named aggregation" 实现。

    In [79]: animals = 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]})
       ....: 
    
    In [80]: animals
    Out[80]: 
      kind  height  weight
    0  cat     9.1     7.9
    1  dog     6.0     7.5
    2  cat     9.5     9.9
    3  dog    34.0   198.0
    
    In [82]: animals.groupby("kind").agg(
       ....:     min_height=('height', 'min'),
       ....:     max_height=('height', 'max'),
       ....:     average_weight=('weight', np.mean),
       ....: )
       ....: 
    Out[82]: 
          min_height  max_height  average_weight
    kind                                        
    cat          9.1         9.5            8.90
    dog          6.0        34.0          102.75
    

    之前不推荐使用的版本如下:


    例如,您可以将字典字典传递给.agg 映射{column: {name: aggfunc}}

    In [46]: df.head()
    Out[46]:
       Year  qtr  realgdp  realcons  realinvs  realgovt  realdpi  cpi_u      M1  \
    0  1950    1   1610.5    1058.9     198.1     361.0   1186.1   70.6  110.20
    1  1950    2   1658.8    1075.9     220.4     366.4   1178.1   71.4  111.75
    2  1950    3   1723.0    1131.0     239.7     359.6   1196.5   73.2  112.95
    3  1950    4   1753.9    1097.6     271.8     382.5   1210.0   74.9  113.93
    4  1951    1   1773.5    1122.8     242.9     421.9   1207.9   77.3  115.08
    
       tbilrate  unemp      pop     infl  realint
    0      1.12    6.4  149.461   0.0000   0.0000
    1      1.17    5.6  150.260   4.5071  -3.3404
    2      1.23    4.6  151.064   9.9590  -8.7290
    3      1.35    4.2  151.871   9.1834  -7.8301
    4      1.40    3.5  152.393  12.6160 -11.2160
    
    In [47]: df.groupby('qtr').agg({"realgdp": {"mean_gdp": "mean", "std_gdp": "std"},
                                    "unemp": {"mean_unemp": "mean"}})
    Out[47]:
             realgdp                   unemp
            mean_gdp      std_gdp mean_unemp
    qtr
    1    4506.439216  2104.195963   5.694118
    2    4546.043137  2121.824090   5.686275
    3    4580.507843  2132.897955   5.662745
    4    4617.592157  2158.132698   5.654902
    

    结果在列中有一个 MultiIndex。如果你不想要那个外层,你可以使用.columns.droplevel(0)

    【讨论】:

    • 谢谢!超级好用!您应该将其添加到官方文档中(除非它已经存在并且我找不到它)
    • 它不在文档中,但在此处正确记录它存在问题:github.com/pydata/pandas/issues/9052 一个拉取请求添加它会很棒,如果你愿意的话!
    • 这已经不可能了。 Python 现在会产生一个警告,“不推荐使用带有重命名的 dict,并将在未来的版本中删除”。为什么,哦,请有人解释为什么!!!!!!
    【解决方案2】:

    我同意这有点令人沮丧,但我确实发现使用 rename 方法进行链接可以达到我的目的。此外,当它变得非常复杂时,我将重置列名。它是一个MultiIndex,所以它是不可变的,你应该对处理关卡感到舒服。

    基于熊猫documentation

    生成的聚合以函数本身命名。如果 您需要重命名,然后您可以添加一个链式操作 像这样的系列

    In [67]: (grouped['C'].agg([np.sum, np.mean, np.std])
       ....:              .rename(columns={'sum': 'foo',
       ....:                               'mean': 'bar',
       ....:                               'std': 'baz'})
       ....: )
       ....: 
    Out[67]: 
              foo       bar       baz
    A                                
    bar  0.392940  0.130980  0.181231
    foo -1.796421 -0.359284  0.912265
    

    当一个函数有多种用途并且您想以不同的方式命名它时,这个question 删除级别并通过下划线连接不同级别会有所帮助。

    如果您确实发现 sql 语法更清晰,有一个名为 pandasql 的库可以为您提供这种灵活性。

    【讨论】:

      猜你喜欢
      • 2015-08-20
      • 1970-01-01
      • 1970-01-01
      • 2019-12-27
      • 2015-12-11
      • 1970-01-01
      • 2013-09-04
      • 2015-10-15
      • 1970-01-01
      相关资源
      最近更新 更多