Python Pandas groupby:如何为参数列表中的每个参数应用聚合函数
我有这样一个数据帧:Python Pandas groupby:如何为参数列表中的每个参数应用聚合函数,python,pandas,pandas-groupby,Python,Pandas,Pandas Groupby,我有这样一个数据帧: 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]}) 我想分组并多次应用一些聚合函数。函数的运行次数和运行参数应是动态的(输出应取决于参数列表) 示例: 假设我想按种类分组,
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]})
我想分组并多次应用一些聚合函数。函数的运行次数和运行参数应是动态的(输出应取决于参数列表)
示例:
假设我想按种类分组,计算平均身高、平均身高+1和平均身高+2,然后我可以运行:
parameters = [0,1,2]
animals.groupby(['kind']).agg(
mean_height = ('height', lambda x: x.mean() + parameters[0]),
mean_height_plus_1 = ('height', lambda x: x.mean() + parameters[1]),
mean_height_plus_2 = ('height', lambda x: x.mean() + parameters[2]))
然而,这要求我提前知道参数列表的长度。但是我想稍后改变主意,对参数=[0,1,2359]
也这样做,而不必手动将代码更改为:
animals.groupby(['kind']).agg(
mean_height = ('height', lambda x: x.mean() + parameters[0]),
mean_height_plus_1 = ('height', lambda x: x.mean() + parameters[1]),
mean_height_plus_2 = ('height', lambda x: x.mean() + parameters[2]),
mean_height_plus_359 = ('height', lambda x: x.mean() + parameters[3]))
例如,您可以使用
params
定义函数并应用:
def get_mean(x, params):
return pd.Series(x.mean() + np.array(params),
index = [f'mean_plus_{i}' for i in params])
animals.groupby('kind').apply(get_mean, parameters)
输出:
kind
cat mean_plus_0 9.3
mean_plus_1 10.3
mean_plus_2 11.3
dog mean_plus_0 20.0
mean_plus_1 21.0
mean_plus_2 22.0
Name: height, dtype: float64
mean_plus_0 mean_plus_1 mean_plus_2
kind
cat 9.3 10.3 11.3
dog 20.0 21.0 22.0
或者您可以为循环执行:
groups = animals.groupby('kind')
ret_df = pd.DataFrame()
for i in parameters:
ret_df[f'mean_plus_{i}'] = groups['height'].mean() + i
输出:
kind
cat mean_plus_0 9.3
mean_plus_1 10.3
mean_plus_2 11.3
dog mean_plus_0 20.0
mean_plus_1 21.0
mean_plus_2 22.0
Name: height, dtype: float64
mean_plus_0 mean_plus_1 mean_plus_2
kind
cat 9.3 10.3 11.3
dog 20.0 21.0 22.0
非常感谢。您希望其中一个方法更快吗?方法2会快一点,因为groupby().mean()
是矢量化的(跨组),而groupby().apply()
不是。但差别很小。