Pandas dataframe множественная групповая фильтрация - PullRequest
0 голосов
/ 07 июня 2018

У меня есть следующий фрейм данных:

df2 = pd.DataFrame({'season':[1,1,1,2,2,2,3,3],'value' : [-2, 3,1,5,8,6,7,5], 'test':[3,2,6,8,7,4,25,2],'test2':[4,5,7,8,9,10,11,12]},index=['2020', '2020', '2020','2020', '2020', '2021', '2021', '2021']) 
df2.index=  pd.to_datetime(df2.index)  
df2.index = df2.index.year
print(df2)

        season  test  test2  value
2020       1     3      4     -2
2020       1     2      5      3
2020       1     6      7      1
2020       2     8      8      5
2020       2     7      9      8
2021       2     4     10      6
2021       3    25     11      7
2021       3     2     12      5

Я бы хотел отфильтровать его, чтобы получить для каждого года и каждого сезона этого года максимальное значение столбца «значение».Как я могу сделать это эффективно?

Ожидаемый результат:

print(df_result)

        season  value  test  test2
year                            
2020       1      3     2      5
2020       2      8     7      9
2021       2      6     4     10
2021       3      7     25    11

Спасибо за вашу помощь,

Пьер

Ответы [ 3 ]

0 голосов
/ 07 июня 2018

Вы можете повысить свой индекс до серии, а затем выполнить операцию groupby со списком столбцов:

df2['year'] = df2.index
df_result = df2.groupby(['year', 'season'])['value'].max().reset_index()

print(df_result)

   year  season  value
0  2020       1      4
1  2020       2      8
2  2021       2      6
3  2021       3      7

Если хотите, вы можете сделать year свой индекс снова через df_result = df_result.set_index('year').

Чтобы сохранить другие столбцы, используйте:

df2['year'] = df2.index
df2['value'] = df2.groupby(['year', 'season'])['value'].transform('max')

Затем удалите дубликаты с помощью pd.DataFrame.drop_duplicates.

Обновление # 1

Для вашего новоготребование, вам необходимо применить функцию агрегирования для 2 серий:

df2['year'] = df2.index

df_result = df2.groupby(['year', 'season'])\
               .agg({'value': 'max', 'test': 'last'})\
               .reset_index()

print(df_result)

   year  season  value  test
0  2020       1      4     6
1  2020       2      8     7
2  2021       2      6     2
3  2021       3      7     2

Обновление # 2

Для вашего окончательного требования:

df2['year'] = df2.index

df2['max_value'] = df2.groupby(['year', 'season'])['value'].transform('max')

df_result = df2.loc[df2['value'] == df2['max_value']]\
               .drop_duplicates(['year', 'season'])\
               .drop('max_value', 1)


print(df_result)

      season  value  test  test2  year
2020       1      3     2      5  2020
2020       2      8     7      9  2020
2021       2      6     4     10  2021
2021       3      7    25     11  2021
0 голосов
/ 07 июня 2018

Вы можете использовать get_level_values для приведения значения индекса в groupby

df2.groupby([df2.index.get_level_values(0),df2.season]).value.max().reset_index(level=1)
Out[38]: 
      season  value
2020       1      4
2020       2      8
2021       2      6
2021       3      7
0 голосов
/ 07 июня 2018

Это groupby операция, но немного нетривиальная, поэтому отправка в качестве ответа.

(df2.set_index('season', append=True)
    .groupby(level=[0, 1])
    .value.max()
    .reset_index(level=1)
)
      season  value
2020       1      4
2020       2      8
2021       2      6
2021       3      7
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...