Pandas数据帧通过多个groupby过滤

时间:2018-06-07 16:36:56

标签: python pandas dataframe group-by pandas-groupby

我有以下数据框:

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 :(得分:3)

这是一个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

答案 1 :(得分:2)

您可以将索引提升为系列,然后对列列表执行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

答案 2 :(得分:1)

您可以使用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