Cle*_*leb 3 python group-by dataframe pandas
我有这样的数据帧:
import pandas as pd
df = pd.DataFrame({'id': [1, 2, 1, 1, 2, 1, 2, 2],
'min_max': ['max_val', 'max_val', 'min_val', 'min_val', 'max_val', 'max_val', 'min_val', 'min_val'],
'value': [1, 20, 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
Run Code Online (Sandbox Code Playgroud)
每个id都有几个与之相关的最大值和最小值.我想要的输出如下:
max min
id
1 3 10
2 20 -10
Run Code Online (Sandbox Code Playgroud)
它包含每个的最大值max_val和最小值.min_valid
目前我实现如下:
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']
Run Code Online (Sandbox Code Playgroud)
我不喜欢的是,我必须打电话.max()和.min()分组数据gdf框,分别在哪里丢弃50%的信息(因为我对最大min_val和最小的不感兴趣min_val).
有没有办法以更简单的方式执行此操作,例如将应该应用于组的函数直接传递给groupby调用?
编辑:
df.groupby('id')['value'].agg(['max','min'])
Run Code Online (Sandbox Code Playgroud)
是不够的,因为可能存在一个组具有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
Run Code Online (Sandbox Code Playgroud)
上面代码的结果:
max min
id
1 3 10
2 20 -10
Run Code Online (Sandbox Code Playgroud)
这是一个略显诙谐的解决方案:
>>> 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
Run Code Online (Sandbox Code Playgroud)
这将应用一个函数,该函数从组密钥中获取要应用的实函数的名称.
显然,如果字符串"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()
Run Code Online (Sandbox Code Playgroud)
请注意,这比上面的版本效率稍低,因为它调用普通的Python max/min而不是优化的pandas版本.但是如果你想要一个更通用的解决方案,那就是你必须要做的事情,因为没有优化的pandas版本.(这也或多或少地为什么没有内置的方法来执行此操作:对于大多数数据,您不能假设您的值可以映射到有意义的函数,因此尝试确定没有意义基于值本身应用的函数.)
| 归档时间: |
|
| 查看次数: |
631 次 |
| 最近记录: |