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

ylamdve6  于 2023-01-28  发布在  Python
关注(0)|答案(8)|浏览(161)

pandas drop_duplicates函数非常适合“唯一化”一个 Dataframe 。我想删除所有在列的子集中重复的行。这可能吗?

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

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

kknvjkwl

kknvjkwl1#

现在在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)
tcbh2hod

tcbh2hod2#

只想补充一下Ben对drop_duplicates的回答:
keep:{"第一个","最后一个",False},默认值为"第一个"

  • first:删除除第一个匹配项之外的重复项。
  • last:删除除最后一个匹配项之外的重复项。
      • False:删除所有重复项。**

因此,将keep设置为False将得到您想要的答案。
DataFrame. drop_duplicates(* args,**kwargs)返回删除了重复行的DataFrame,也可以只考虑某些列
参数:子集:列标签或标签序列,可选仅考虑某些列来标识重复项,默认情况下使用所有列keep:{"第一个","最后一个",False},默认为"第一个"第一个:删除除第一个匹配项之外的重复项。最后一个:删除除最后一个匹配项之外的重复项。False:删除所有重复项。take_last:不建议在原处使用:boolean,default False是删除原地的重复项还是返回列的副本:子集的唯一kwargs参数[已弃用]返回:重复数据消除:数据框

9w11ddsr

9w11ddsr3#

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

df.drop_duplicates(keep=False)

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

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

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

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

u3r8eeie

u3r8eeie4#

使用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)
34gzjxbg

34gzjxbg5#

"尝试各种各样的事情"

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')
ogq8wdun

ogq8wdun6#

实际上,删除第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]
ruarlubt

ruarlubt7#

可以使用duplicated()标记所有重复项并过滤掉标记的行。如果以后需要将列分配给new_df,请确保调用.copy(),这样以后就不会得到SettingWithCopyWarning

new_df = df[~df.duplicated(subset=['A', 'C'], keep=False)].copy()

此方法的一个很好的特性是可以有条件地删除重复项。例如,要仅在列A等于'foo'时删除所有重复行,可以使用以下代码。

new_df = df[~( df.duplicated(subset=['A', 'B', 'C'], keep=False) & df['A'].eq('foo') )].copy()

另外,如果不希望按名称写出列,可以将df.columns的切片传递给subset=,对于drop_duplicates()也是如此。

# to consider all columns for identifying duplicates
df[~df.duplicated(subset=df.columns, keep=False)].copy()

# the same is true for drop_duplicates
df.drop_duplicates(subset=df.columns, keep=False)

# to consider columns in positions 0 and 2 (i.e. 'A' and 'C') for identifying duplicates
df.drop_duplicates(subset=df.columns[[0, 2]], keep=False)
r7xajy2e

r7xajy2e8#

如果您想用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}.")

相关问题