如何将不同的函数应用于groupby对象?
我有这样的数据帧:
import pandas as pd df = pd.DataFrame({'id': [1,2,1,2],'min_max': ['max_val','max_val','min_val','min_val'],'value': [1,20,10,12,3,-10,-5 ]}) id min_max value 0 1 max_val 1 1 2 max_val 20 2 1 min_val 20 3 1 min_val 10 4 2 max_val 12 5 1 max_val 3 6 2 min_val -10 7 2 min_val -5 每个id都有几个与之关联的最大值和最小值.我想要的输出如下: max min id 1 3 10 2 20 -10 它包含每个id的最大max_val和最小min_val. 目前我实现如下: gdf = df.groupby(by=['id','min_max'])['value'] max_max = gdf.max().loc[:,'max_val'] min_min = gdf.min().loc[:,'min_val'] final_df = pd.concat([max_max,min_min],axis=1) final_df.columns = ['max','min'] 我不喜欢的是我必须在分组的数据帧gdf上调用.max()和.min(),我将丢弃50%的信息(因为我对最大min_val和最小值不感兴趣) MIN_VAL). 有没有办法以更直接的方式做到这一点,例如将应该应用于组的函数直接传递给groupby调用? 编辑: df.groupby('id')['value'].agg(['max','min']) 是不够的,因为可能存在一个组的min_val高于该组的所有max_val或max_val低于所有min_val的情况.因此,还必须基于列min_max进行分组. 结果 df.groupby('id')['value'].agg(['max','min']) max min id 1 20 1 2 20 -10 上面代码的结果: max min id 1 3 10 2 20 -10 解决方法
这是一个略显诙谐的解决方案:
>>> df.groupby(['id','min_max'])['value'].apply(lambda g: getattr(g,g.name[1][:3])()).unstack() min_max max_val min_val id 1 3 10 2 20 -10 这将应用一个函数,该函数从组密钥中获取要应用的实函数的名称. 显然,如果字符串“max_val”和函数名“max”之间没有这么简单的关系,那么这就行不通.它可以通过将dict映射列值映射到要应用的函数来推广,如下所示: func_map = {'min_val': min,'max_val': max} df.groupby(['id','min_max'])['value'].apply(lambda g: func_map[g.name[1]](g)).unstack() 请注意,这比上面的版本效率稍低,因为它调用普通的Python max / min而不是优化的pandas版本.但是如果你想要一个更通用的解决方案,那就是你必须要做的事情,因为没有优化的pandas版本. (这也或多或少地为什么没有内置的方法来执行此操作:对于大多数数据,您不能假设您的值可以映射到有意义的函数,因此尝试确定没有意义基于值本身应用的函数.) (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |