我试图基于两列过滤熊猫数据框,以便对于第一列中的每个值只保留那些行,其中第二列是最小的。我知道这样听起来很混乱,所以这里有个例子:
> df = pd.DataFrame([{'a':'anno1', 'ppm':1},{'a':'anno1', 'ppm':2},{'a':'anno2', 'ppm':2},{'a':'anno2', 'ppm':2}])
> df
a ppm
0 anno1 1
1 anno1 2
2 anno2 2
3 anno2 2
我想要行0,2和3,因为对于anno1
,最小ppm
是1
,对于anno2
,最小ppm
是2
(保留两行!)。所以我从groupby
开始:
> grouped_series = df.groupby(['a']).ppm.min()
> grouped_series
a
anno1 1
anno2 2
现在,对于a
中的每个值,我都有最小值ppm
。但是,如何使用该系列过滤原始数据帧?还是有更简单的方法来做到这一点?我尝试了以下几种变化:
new_df = df.loc[ df.loc[:,'ppm']==grouped_series.loc[df.loc[:,'a']] , :]
但这给了我ValueError: Can only compare identically-labeled Series objects
答案 0 :(得分:1)
使用GroupBy.transform
将Series
的最小值用作与df
相同的大小,因此比较效果不错,也不需要在loc
的{{3}}中进行过滤:
new_df = df[df['ppm'] == df.groupby('a').ppm.transform('min')]
print (new_df)
a ppm
0 anno1 1
2 anno2 2
3 anno2 2
答案 1 :(得分:0)
如果您不介意重置原始索引,这里是另一种方法:
df.merge(df.groupby(['a'])['ppm'].min().reset_index(), how='inner')
输出:
a ppm
0 anno1 1
1 anno2 2
2 anno2 2