在 Python Pandas 中删除多列中的所有重复行
Posted
技术标签:
【中文标题】在 Python Pandas 中删除多列中的所有重复行【英文标题】:Drop all duplicate rows across multiple columns in Python Pandas 【发布时间】:2014-05-15 00:31:47 【问题描述】:pandas
drop_duplicates
函数非常适合“唯一化”数据帧。但是,要传递的关键字参数之一是take_last=True
或take_last=False
,而我想删除在列子集中重复的所有行。这可能吗?
A B C
0 foo 0 A
1 foo 1 A
2 foo 1 B
3 bar 1 A
例如,我想删除与列 A
和 C
匹配的行,所以这应该删除第 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
定义为first
或last
,您将至少保留一条记录。它不适用于该问题,但如果您的子集是单列(如我的情况),则此信息在处理 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】:使用groupby
和filter
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在具有多个条件的多列上
比较季度数据:Python(Pandas) 中的迭代以比较来自作为数据框导入的四个不同 excel 文件的多列
100天精通Python(数据分析篇)——第69天:Pandas常用数据筛选方法(betweenisinlociloc)