熊猫数据帧多个分组按筛选



我有以下数据帧:

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

谢谢你的帮助,

皮尔

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

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

如果您愿意,可以通过df_result = df_result.set_index('year')再次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

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

最新更新