在Python Pandas中删除多个列中的所有重复行

pandas drop_duplicates函数非常适合“唯一化”一个数据帧。然而,要传递的关键字参数之一是take_last=Truetake_last=False,而我想删除在列子集中重复的所有行。这可能吗?

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

例如,我想删除与列AC匹配的行,因此这应该删除行0和1。

501527 次浏览

实际上,删除行0和1只需要(任何包含匹配的A和C的观测值都被保留):

In [335]:


df['AC']=df.A+df.C
In [336]:


print df.drop_duplicates('C', take_last=True) #this dataset is a special case, in general, one may need to first drop_duplicates by 'c' and then by 'a'.
A  B  C    AC
2  foo  1  B  fooB
3  bar  1  A  barA


[2 rows x 4 columns]

但我怀疑你真正想要的是这个(一个包含匹配的A和C的观察结果被保留):

In [337]:


print df.drop_duplicates('AC')
A  B  C    AC
0  foo  0  A  fooA
2  foo  1  B  fooB
3  bar  1  A  barA


[3 rows x 4 columns]

编辑:

因此,现在情况清楚多了:

In [352]:
DG=df.groupby(['A', 'C'])
print pd.concat([DG.get_group(item) for item, value in DG.groups.items() if len(value)==1])
A  B  C
2  foo  1  B
3  bar  1  A


[2 rows x 3 columns]

使用groupbyfilter

import pandas as pd
df = pd.DataFrame({"A":["foo", "foo", "foo", "bar"], "B":[0,1,1,1], "C":["A","A","B","A"]})
df.groupby(["A", "C"]).filter(lambda df:df.shape[0] == 1)

现在在pandas中,通过drop_duplicates和keep参数,这要容易得多。

import pandas as pd
df = pd.DataFrame({"A":["foo", "foo", "foo", "bar"], "B":[0,1,1,1], "C":["A","A","B","A"]})
df.drop_duplicates(subset=['A', 'C'], keep=False)

只是想补充一下Ben关于drop_duplicates的答案:

keep: {' first ', ' last ', False},默认' first '

  • first:删除除第一次出现之外的重复项。

  • last:删除除最后一次出现之外的重复项。

  • False:删除所有副本

因此,将keep设置为False将给你想要的答案。

< p > DataFrame。drop_duplicate (*args, **kwargs)返回DataFrame 删除重复行,只考虑某些列

参数:子集:列标签或标签序列,可选 默认情况下,只考虑某些列来标识重复项 使用所有列保持:{' first ', ' last ', False},默认 ' first ' first:删除除第一次出现之外的重复项。最后的 :删除除最后一个重复项以外的重复项。错误:删除所有 重复。take_last:已弃用inplace: boolean,默认为False 是否在适当的位置删除副本或返回副本 子集的唯一参数[deprecated]返回:重复数据删除: DataFrame < / p >

如果你想将结果存储在另一个数据集中:

df.drop_duplicates(keep=False)

df.drop_duplicates(keep=False, inplace=False)

如果需要更新相同的数据集:

df.drop_duplicates(keep=False, inplace=True)

上面的例子将删除所有重复项并保留一个,类似于SQL中的DISTINCT *

试试这些不同的方法

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


>>>df.drop_duplicates( "A" , keep='first')

>>>df.drop_duplicates( keep='first')

>>>df.drop_duplicates( keep='last')

如果你想用try和except语句检查两列,这个可以帮你。

if "column_2" in df.columns:
try:
df[['column_1', "column_2"]] = df[['header', "column_2"]].drop_duplicates(subset = ["column_2", "column_1"] ,keep="first")
except:
df[["column_2"]] = df[["column_2"]].drop_duplicates(subset="column_2" ,keep="first")
print(f"No column_1 for {path}.")
try:
df[["column_1"]] = df[["column_1"]].drop_duplicates(subset="column_1" ,keep="first")
except:
print(f"No column_1 or column_2 for {path}.")