我有一个如下所示的数据框
op1 = pd.DataFrame({
'subject_id':[1,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,2],
'date' : ['1/1/2017','1/1/2017','1/1/2017','1/2/2017','1/2/2017','1/2/2017','1/3/2017','1/3/2017','1/3/2017','1/4/2017','1/4/2017','1/4/2017','1/5/2017','1/5/2017','1/5/2017',
'1/6/2017','1/6/2017','1/6/2017'],
'val' :[5,5,11,10,5,7,16,12,11,21,23,26,6,8,5,11,10,3]
})
我想做的是每天获取每个科目的 min 和 max。
虽然我的代码在下面工作,我觉得可以用更好的方式编写
t1 = op1.groupby(['subject_id','date'])['val'].max().reset_index()
t2 = op1.groupby(['subject_id','date'])['val'].min().reset_index()
t1.merge(t2,on=['subject_id','date'],how='inner',suffixes=('_max', '_min'))
输出应该如下所示。虽然我的代码有效,但我觉得它并不优雅。有没有其他方法可以将 max 和 min 写在一行中?
请您参考如下方法:
使用GroupBy.agg带有新列名和聚合函数的元组:
df = (op1.groupby(['subject_id','date'])['val']
.agg([('val_max', 'max'),('val_min', 'min')])
.reset_index())
print (df)
subject_id date val_max val_min
0 1 1/1/2017 11 5
1 1 1/2/2017 10 5
2 1 1/3/2017 16 11
3 2 1/4/2017 26 21
4 2 1/5/2017 8 5
5 2 1/6/2017 11 3
在 Pandas 中 0.25+可以使用命名聚合:
df = (op1.groupby(['subject_id','date'])
.agg(val_min=pd.NamedAgg(column='val', aggfunc='min'),
val_max=pd.NamedAgg(column='val', aggfunc='max'))
.reset_index())
