我想删除col1
的重复值,只在col2
中保存具有最高值的行。 df示例:
df1 = pd.DataFrame({'col1': ['a', 'a', 'b', 'b', 'c'],
'col2': [5, 5, 10, 15, 20]})
我知道df1.drop_duplicates
将消除重复的值,但是如何确保它是保存的最高值(如果有最高值,则保存多个值)?
所需的输出:
dfoutput = pd.DataFrame({'col1': ['a', 'a', 'b', 'c'],
'col2': [5, 5, 15, 20]})
答案 0 :(得分:3)
您可以使用Pandas的rank功能:
将等级分配给组的每一行。如果值相同,则行将具有相同的等级。如下所示:
In [126]: df1['rnk'] = df1.groupby('col1')['col2'].rank()
In [127]: df1
Out[127]:
col1 col2 rnk
0 a 5 1.5
1 a 5 1.5
2 b 10 1.0
3 b 15 2.0
4 c 20 1.0
然后使用query方法仅过滤小于2.0
的排名:
In [129]: df1.query('rnk < 2.0').drop('rnk',1)
Out[129]:
col1 col2
0 a 5
1 a 5
2 b 10
4 c 20
In [130]: df1[df1.groupby('col1')['col2'].rank() < 2]
Out[130]:
col1 col2
0 a 5
1 a 5
2 b 10
4 c 20
答案 1 :(得分:2)
首先按降序对DataFrame进行排序。接下来,计算两个掩码,一个掩码用于确定组中最大的行,另一个掩码用于确定重复的行。
然后我们可以结合使用这些掩码来确定哪些行重复了和,而不是它们各自组中的最大值,然后执行最后一个过滤步骤。
v = df1.sort_values('col2', ascending=False)
m1 = v['col2'] == v.groupby('col1', sort=False)['col2'].transform('max')
m2 = v.duplicated('col1')
v[~(m2 & ~m1)].sort_index() # v[~m2 | m1] - DeMorgan's Law
col1 col2
0 a 5
1 a 5
3 b 15
4 c 20
答案 2 :(得分:1)
我发现的另一种方法:
获取重复项并按decending
顺序排序后,将重复数据删除后的值附加到重复数据上,然后删除重复的索引。
dfoutput = df1[df1.duplicated(keep=False)].append(df1.sort_values(['col1','col2'],ascending=False).drop_duplicates(['col1']))
dfoutput[~dfoutput.index.duplicated()].sort_index()
col1 col2
0 a 5
1 a 5
3 b 15
4 c 20