Элегантный способ получить минимум и максимум используя панд - PullRequest
1 голос
/ 11 октября 2019

У меня есть датафрейм, как показано ниже

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 в одну строку?

enter image description here

1 Ответ

7 голосов
/ 11 октября 2019

Используйте 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

В пандах 0.25 + возможно использование named aggregation:

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())
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...