将不同聚合函数应用于数据帧的不同列的Python方法?为了高效地命名列? 我的问题

将不同聚合函数应用于数据帧的不同列的Python方法?为了高效地命名列? 我的问题,python,pandas,dataframe,pandas-groupby,Python,Pandas,Dataframe,Pandas Groupby,在SQL中,很容易将不同的聚合函数应用于不同的列,例如: select item, sum(a) as [sum of a], avg(b) as [avg of b], min(c) as [min of c] 在熊猫身上,没有那么多。 提供的解决方案已被弃用: df.groupby('qtr').agg({"realgdp": {"mean_gdp": "mean", "std_gdp": "std&

在SQL中,很容易将不同的聚合函数应用于不同的列,例如:

select item, sum(a) as [sum of a], avg(b) as [avg of b], min(c) as [min of c]
在熊猫身上,没有那么多。 提供的解决方案已被弃用:

df.groupby('qtr').agg({"realgdp": {"mean_gdp": "mean", "std_gdp": "std"},
                                "unemp": {"mean_unemp": "mean"}})
我的解决方案 我设法找到的最差解决方案(主要基于我无法再找到的其他堆栈溢出问题)类似于底部的玩具示例,其中我:

  • 定义一个包含我需要的所有计算的函数
  • 分别计算每一列,然后将它们放在一个数据框中
  • 将函数作为lambda函数应用:
我想改进的是:命名列 如果您只需要创建2或3列,那么这个解决方案非常好

但是,如果有许多列要计算,那么命名它们会变得非常复杂,而且非常容易出错:我必须创建一个列名称列表,并将该列表作为函数创建的数据帧的索引传递

现在想象一下,我已经有12列了,需要再添加3列;我可能会造成一些混乱,并以错误的顺序添加相应的列名

将此与SQL进行比较,SQL在定义计算后立即分配名称-区别在于白天和黑夜

有更好的方法吗?例如,在定义计算的同时指定列名称的方法

为什么这不是一个重复的问题 问题的重点是如何命名列,以尽量减少错误和混淆的风险。有一些类似的问题基于现在不推荐的pandas功能,或者提供自动列命名的答案,但据我所知,没有问题关注这一点

玩具示例
我不是专家,但我通常使用这样的字典:

将熊猫作为pd导入
将numpy作为np导入
df=pd.DataFrame(列=['a','b','c','d',数据=np.random.rand(300,4))
df['city']=np.重复(['London','NewYork','Buenos Aires',100)
def func(x,df):
#在lambda函数中调用func();x是行,df是整个表
s_dict={}
s_dict['a'之和]=x['a'].sum()
s_dict['%of a']=x['a'].sum()/df['a'].sum(),如果df['a'].sum()=0.np.nan
s_dict['b'的平均值]=x['b'].平均值()
s_dict['a的加权平均值,由b'加权]=(x['a']*x['b']).sum()/x['b'].sum()如果x['b'].sum()大于0,则为np.nan
s_dict['c'之和]=x['c'].sum()
s_dict['d'之和]=x['d'].sum()
返回pd.系列(s_dict)
out=df.groupby('city')。应用(lambda x:func(x,df))

简洁性卓越-谢谢!我应该考虑一下:(
import pandas as pd
import numpy as np

df = pd.DataFrame(columns =['a','b','c','d'], data = np.random.rand(300,4))
df['city'] = np.repeat(['London','New York','Buenos Aires'], 100)

def func(x, df):
    # func() gets called within a lambda function; x is the row, df is the entire table    
    b1 = x['a'].sum()
    b2 = x['a'].sum() / df['a'].sum() if df['a'].sum() !=0 else np.nan
    
    b3 = x['b'].mean()
    
    b4 = ( x['a'] * x['b']).sum() / x['b'].sum() if x['b'].sum() >0 else np.nan
    
    b5 = x['c'].sum()
    b6 = x['d'].sum()
    
    
    cols = ['sum of a',
            '% of a',
            'avg of b',
            'weighted avg of a, weighted by b', 
            'sum of c',
            'sum of d']
    

    return pd.Series( [b1, b2, b3, b4, b5, b6] , index = cols ) 

out = df.groupby('city').apply(lambda x: func(x,df))