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

Posted

技术标签:

【中文标题】在 Python Pandas 中删除多列中的所有重复行【英文标题】:Drop all duplicate rows across multiple columns in Python Pandas 【发布时间】:2014-05-15 00:31:47 【问题描述】:

pandasdrop_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 行。

【问题讨论】:

【参考方案1】:

现在有了drop_duplicates 和keep 参数,这在pandas 中变得容易多了。

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)

【讨论】:

如果我的列没有明确标记怎么办?如何仅根据索引选择列? 可能是df.reindex(df.iloc[:,[0,2]].drop_duplicates(keep=False).index)? 你可以试试df.drop_duplicates(subset=[df.columns[0:2]], keep = False) 如果您的subset 只是像A 这样的单列,keep=False 将删除所有行。如果您将keep 定义为firstlast,您将至少保留一条记录。它不适用于该问题,但如果您的子集是单列(如我的情况),则此信息在处理 drop_duplicates 方法时可能会有所帮助:您可能会丢失很多记录,而不仅仅是删除重复项。问候:)。【参考方案2】:

只想在 drop_duplicates 上添加到 Ben 的答案:

keep: ‘first’, ‘last’, False,默认‘first’

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

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

False:删除所有重复项。

所以将keep 设置为 False 会给你想要的答案。

DataFrame.drop_duplicates(*args, **kwargs) 返回 DataFrame 删除重复行,可选地仅考虑某些列

参数:subset:列标签或标签序列,可选 默认情况下,仅考虑某些列来识别重复项 使用所有列保持:'first','last',False,默认 ‘first’ first :删除除第一次出现的重复项。最后的 :删除除最后一次出现的重复项。假:全部丢弃 重复。 take_last :就地弃用:布尔值,默认为 False 是否删除重复项或返回副本 cols : kwargs 子集的唯一参数 [已弃用] 返回:去重: 数据帧

【讨论】:

【参考方案3】:

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

df.drop_duplicates(keep=False)

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

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

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

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

【讨论】:

【参考方案4】:

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

【讨论】:

【参考方案5】:

尝试这些不同的东西

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

【讨论】:

【参考方案6】:

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

【讨论】:

如果那是我想要的,我会使用 df.drop_duplicates(['A','C']) 作为默认值,就像我在问题中提到的那样,保持一个观察结果是第一个或最后一个 - 尽管我刚刚意识到我有关键字错误,因为我是凭记忆写的。我想要的是删除感兴趣的列上所有相同的行(示例数据中的 A 和 C)。

以上是关于在 Python Pandas 中删除多列中的所有重复行的主要内容,如果未能解决你的问题,请参考以下文章

pandas python中的COUNTIF在具有多个条件的多列上

如何使用 Pandas 计算跨多列的行中的值?

比较季度数据:Python(Pandas) 中的迭代以比较来自作为数据框导入的四个不同 excel 文件的多列

无法在pandas中通过lambda填充多列中的NaN值

100天精通Python(数据分析篇)——第69天:Pandas常用数据筛选方法(betweenisinlociloc)

在 Python/Pandas 中执行不同操作的多列有条件地聚合分组数据