如何在pandas数据框中删除唯一的行?

18
我是一个有用的助手,可以为您进行文本翻译。以下是需要翻译的内容:

我遇到了一个看似简单的问题:如何在pandas数据框中删除唯一的行。基本上,与drop_duplicates()相反。

假设这是我的数据:

    A       B   C  
0   foo     0   A
1   foo     1   A
2   foo     1   B
3   bar     1   A

我希望删除A和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)]

但是我只得到了第二行,因为0、1和3已经在唯一值里了!
3个回答

21

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

您可以使用 duplicated 函数,并设置参数 keep=False 来选择所有的重复项:

df = df[df.duplicated(subset=['A','B'], keep=False)]
print (df)
     A  B  C
1  foo  1  A
2  foo  1  B

使用 transform方法的解决方案:
df = df[df.groupby(['A', 'B'])['A'].transform('size') > 1]
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 = df[~df.fillna('').duplicated(subset=['A','B'], keep=False)] 应该可以解决问题。但是我没有你的真实数据,所以很难回答。 - jezrael
我的原始数据集中df[~df.duplicated(subset=['A','B'], keep=False)]df[df.groupby(['A', 'B'])['A'].transform('size') == 1]都没有返回任何结果(这两种方法在示例中是有效的)。 - toto_tico
但是在我看来,如果数据不好,那么需要更深入地分析假阳性行,没有数据是不可能的。 - jezrael
这对于我的当前需求来说已经足够了,我正在分析数据库以寻找异常情况 - 如果我弄清楚发生了什么,我会发布的。非常感谢你的帮助! - toto_tico
很高兴能帮忙!祝你好运! - jezrael
显示剩余4条评论

3

我使用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_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 回答,我认为这样做是最安全的,因为我在这里使用了 pandas 的索引。

1
df1 = df.drop_duplicates(['A', 'B'],keep=False)

df1 = pd.concat([df, df1])

df1 = df1.drop_duplicates(keep=False)

当你有两个包含数百万条记录的数据集dfXdfY时,这种技术更加适用。你可以先将dfXdfY连接起来,然后按照相同的步骤进行操作。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接