Pandas - 与删除重复项相反,先保留

chi*_*n88 9 python pandas drop-duplicates

first我熟悉如何删除重复行,然后使用, last,参数none。没有什么太复杂的,并且有很多例子(即这里)。

但是,我正在寻找的是有一种方法可以找到重复项,但不是删除所有重复项并保留第一个,如果我有重复项,请保留所有重复项但删除第一个:

因此,我不想“如果重复则删除,保留第一个”,而是“如果重复则保留,首先删除”

例子:

给定这个数据框,并查看cost列中的重复项:

    ID name type cost
0    0    a   bb    1
1    1    a   cc    2 <--- there are duplicates, so drop this row
2  1_0    a   dd    2
3    2    a   ee    3 <--- there are duplicates, so drop this row
4  2_0    a   ff    3
5  2_1    a   gg    3
6  2_2    a   hh    3
Run Code Online (Sandbox Code Playgroud)

如果列中存在重复项cost,则只需删除第一个出现的项,但保留其余的项。

所以我的输出是:

    ID name type cost
0    0    a   bb    1
2  1_0    a   dd    2
4  2_0    a   ff    3
5  2_1    a   gg    3
6  2_2    a   hh    3
Run Code Online (Sandbox Code Playgroud)

这是示例数据框:

import pandas as pd

df = pd.DataFrame([
['0',   'a',    'bb',   '1'],
['1',   'a',    'cc',   '2'],
['1_0', 'a',    'dd',   '2'],
['2',   'a',    'ee',   '3'],
['2_0', 'a',    'ff',   '3'],
['2_1', 'a',    'gg',   '3'],
['2_2', 'a',    'hh',   '3']], columns = ['ID', 'name', 'type', 'cost'])
Run Code Online (Sandbox Code Playgroud)

jez*_*ael 8

您可以链接使用DataFrame.duplicatedwith bitwise创建的 2 个掩码OR并按以下方式过滤boolean indexing

df = df[df.duplicated('cost') | ~df.duplicated('cost', keep=False)]
print (df)
    ID name type cost
0    0    a   bb    1
2  1_0    a   dd    2
4  2_0    a   ff    3
5  2_1    a   gg    3
6  2_2    a   hh    3
Run Code Online (Sandbox Code Playgroud)

细节

print (df.assign(mask1=df.duplicated('cost'), mask2=~df.duplicated('cost', keep=False)))
    ID name type cost  mask1  mask2
0    0    a   bb    1  False   True
1    1    a   cc    2  False  False
2  1_0    a   dd    2   True  False
3    2    a   ee    3  False  False
4  2_0    a   ff    3   True  False
5  2_1    a   gg    3   True  False
6  2_2    a   hh    3   True  False
Run Code Online (Sandbox Code Playgroud)