python - 将不同聚合函数应用于熊猫数据框的不同列的 Pythonic 方式?并有效地命名列?
问题描述
我的问题
在 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 进行比较,您在定义计算后立即分配名称 - 区别在于白天和黑夜。
有没有更好的办法?例如,在我定义计算的同时分配列名称的方法?
为什么这不是重复的问题
该问题的重点是如何命名列,以最大程度地减少错误和混淆的风险。基于现已弃用的 pandas 功能,或者提供自动命名列的答案,有一些类似的问题,但据我所知,没有问题关注这一点。
玩具示例
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))
解决方案
我不是专家,但我通常会使用这样的字典:
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
s_dict = {}
s_dict['sum of a'] = x['a'].sum()
s_dict['% of a'] = x['a'].sum() / df['a'].sum() if df['a'].sum() !=0 else np.nan
s_dict['avg of b'] = x['b'].mean()
s_dict['weighted avg of a, weighted by b'] = ( x['a'] * x['b']).sum() / x['b'].sum() if x['b'].sum() >0 else np.nan
s_dict['sum of c'] = x['c'].sum()
s_dict['sum of d'] = x['d'].sum()
return pd.Series( s_dict )
out = df.groupby('city').apply(lambda x: func(x,df))
推荐阅读
- asp.net - Jmeter - 不要使用缓存来检索结果
- utf-8 - 为什么十六进制值 C181 在 UTF-8 中不呈现为大写 A?
- r - mode()、storage.mode() 或 typeof() 可以返回“S3”吗?为什么或者为什么不?(他们可以返回“S4”!)
- python - 使用 Apache centos 7 部署 Django 时出错
- javascript - 使用 .map() 时获得未定义的“结果”
- sql-server - 键与表中的任何行都不匹配
- c++ - How to insert an element in a doubly linked list and keep it sorted - c++
- ios - 在静态表格视图中重用表格单元 - iOS - Swift
- javascript - Vue“数据”没有通过html中的输入标签进行更改
- html - Handlebars.net 不保留空白