Python 如何在数据帧中删除唯一的行?

Python 如何在数据帧中删除唯一的行?,python,pandas,dataframe,Python,Pandas,Dataframe,我遇到了一个看似简单的问题:在数据帧中删除唯一的行。基本上,与之相反 假设这是我的数据: A B C 0 foo 0 A 1 foo 1 A 2 foo 1 B 3 bar 1 A 当A、B和B是唯一的时,我想删除这些行,也就是说,我只想保留第1行和第2行 我尝试了以下方法: # Load Dataframe df = pd.DataFrame({"A":["foo", "foo", "foo", "b

我遇到了一个看似简单的问题:在数据帧中删除唯一的行。基本上,与之相反

假设这是我的数据:

    A       B   C  
0   foo     0   A
1   foo     1   A
2   foo     1   B
3   bar     1   A
当A、B和B是唯一的时,我想删除这些行,也就是说,我只想保留第1行和第2行

我尝试了以下方法:

# Load Dataframe
df = pd.DataFrame({"A":["foo", "foo", "foo", "bar"], "B":[0,1,1,1], "C":["A","A","B","A"]})

uniques = df[['A', 'B']].drop_duplicates()
duplicates = df[~df.index.isin(uniques.index)]

但是我只得到第2行,因为0、1和3在unique中

我用
groupby
想出了一个解决方案:

groupped = df.groupby(['A', 'B']).size().reset_index().rename(columns={0: 'count'})
uniques = groupped[groupped['count'] == 1]
duplicates = df[~df.index.isin(uniques.index)]
重复项现在具有正确的结果:

    A       B   C
2   foo     1   B
3   bar     1   A

此外,我在问题中最初的尝试可以通过简单地在
drop\u duplicates
方法中添加
keep=False
来修复:

# Load Dataframe
df = pd.DataFrame({"A":["foo", "foo", "foo", "bar"], "B":[0,1,1,1], "C":["A","A","B","A"]})

uniques = df[['A', 'B']].drop_duplicates(keep=False)
duplicates = df[~df.index.isin(uniques.index)]


请@jezrael回答,我认为这是最安全的(?),因为我在这里使用熊猫索引

选择所有重复行的解决方案:

您可以与子集和参数一起使用
keep=False
来选择所有重复项:

df = df[df.duplicated(subset=['A','B'], keep=False)]
print (df)
     A  B  C
1  foo  1  A
2  foo  1  B
解决方案包括:

对“选择所有唯一行”的解决方案进行了一些修改:

#invert boolean mask by ~
df = df[~df.duplicated(subset=['A','B'], keep=False)]
print (df)
     A  B  C
0  foo  0  A
3  bar  1  A

df = df[df.groupby(['A', 'B'])['A'].transform('size') == 1]
print (df)
     A  B  C
0  foo  0  A
3  bar  1  A

第一个答案有效。第二个是导致少两行(这可能是因为
NaN
,我的数据帧非常脏,无法安全地假定任何内容)。由于某些原因,所有的反转方法都不起作用。因此,
df.duplicated(subset=['A','B',keep=False)
有效,而
df.duplicated(subset=['A','B',keep=False)
not?处理NaNs的想法-我认为
df=df[~df.fillna('')。duplicated(subset=['A','B','],keep=False)]
应该有效。但是我没有真实的数据,所以很难回答。无论是
df[~df.duplicated(subset=['A','B'],keep=False)]
还是
df[df.groupby(['A','B'])['A'].transform('size')==1]
都不会返回我原始数据集中的任何内容(在本例中是有效的)。以及
df[df.groupby(['A','B'])['A'].transform('size')>1]
在原始数据集中少返回两行。。。
#invert boolean mask by ~
df = df[~df.duplicated(subset=['A','B'], keep=False)]
print (df)
     A  B  C
0  foo  0  A
3  bar  1  A

df = df[df.groupby(['A', 'B'])['A'].transform('size') == 1]
print (df)
     A  B  C
0  foo  0  A
3  bar  1  A