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