如何根据python中的多个条件对excel文件进行重复数据删除?
Posted
技术标签:
【中文标题】如何根据python中的多个条件对excel文件进行重复数据删除?【英文标题】:How to dedupe an excel file based on multiple conditions in python? 【发布时间】:2017-12-08 08:28:38 【问题描述】:我有一个 Excel 文件 (attached here)。我必须针对两个或多个重复的 id 对其进行重复数据删除。 重复数据删除的标准基于多种因素。
-
身份证
类型
时间
现在,我手动执行重复数据删除的过程是:
-
我按升序对 id 进行排序。
我为每个以 t 开头的 id 设置 Attribute 为 tid。
我将 xid 用于 id 列中的每个 [id]。如果有重复的 [id](如果两个连续 [id] 的日期相同),我有时会为一个 id 留一个空白。
对于每个重复的 id,我首先检查类型是茶还是咖啡。如果一个是咖啡,另一个是茶,我们将始终偏爱咖啡并将茶的属性设置为“否”。我们可以获得超过 2 个重复项,因此,我们必须为相同 ID 的所有茶设置“否”。如果我们以相同的 ID 获得两杯咖啡和一份茶,那么我们将根据时间保留最新的一份。
如果重复的 id 具有相同的类型,那么我们将查看日期并将旧日期的属性设置为“否”。如果日期相同,那么我们将保留一个并将其他属性设置为“否”。 ID 可以超过两个,但过程相同。
我想做的是:
-
为以 t 开头的 ID 设置属性为 tid。
为具有 [] 的 ID 设置属性为 xid。
如果两个或多个 ID 基于某些条件重复,则在属性中设置 No:
咖啡应该比茶更受欢迎。如果我们有茶和咖啡 重复 id 的类型,我们在每个茶的属性中输入 No 每个重复的 ID。
如果我们为每个重复的 ID 提供一种茶和两种或更多咖啡 然后我们将根据时间(IDs)对剩余的咖啡设置“否” 较旧的时间戳应该是否。)
如果我们对每个重复的 ID 都有相同的类型,那么无论哪个 ID 应保持最新的时间和所有其他属性 应该是没有。
如果我们的所有重复 ID 具有相同的日期和相同的类型,那么我们 只会对除一个之外的所有对象随机设置“否”。
注意:
重复的一、二和三可供我们轻松地根据颜色进行过滤,然后进行重复数据删除。它们基于 Excel 公式:(Duplicate 1=(=IF(B2=B3,1,""), Duplicate2 =(=IF(C1=1,1,""), Duplicate3=(=IF(SUM(C2:D2) >=1,1,"")) 我们无法删除行。 我无法找出任何代码,这是我在关键自动化过程中的障碍。 附件属性栏中有No/xid/tid,供参考。重要问题: - 使用 python 是否可能或可行?
【问题讨论】:
【参考方案1】:我不知道你的问题是否正确,因此我将提供几种不同的方法。
如果您想删除所有包含相同 id、Type 和 Time 值的行,可以这样做:
frame=pd.read_excel(io=r"D:\xxxxxx\test.xlsx")
df=pd.DataFrame(frame)
drop_dup=df.drop_duplicates(subset=("id","Type","Time"))
print(drop_dup)
产生:
id Duplicate 1 Duplicate 2 Total Duplicates \
0 121349100 NaN NaN NaN
1 121350610 NaN NaN NaN
2 124426041 NaN NaN NaN
3 124436734 NaN NaN NaN
4 124451775 1.0 NaN 1.0
5 124451775 1.0 1.0 1.0
7 124463136 NaN NaN NaN
8 124463568 NaN NaN NaN
9 124469946 NaN NaN NaN
10 124474373 NaN NaN NaN
....
Time Type Attribute
0 2017-04-19 18:08:00 Tea NaN
1 2017-04-19 18:08:00 Tea NaN
2 2017-05-05 12:21:00 Tea NaN
3 2017-04-25 15:20:00 Coffee NaN
4 2017-04-05 21:04:00 Coffee No
5 2017-06-05 07:38:00 Tea No
7 2017-06-05 05:40:00 Coffee NaN
8 2017-09-04 23:12:00 Tea NaN
9 2017-04-24 07:48:00 Tea NaN
10 2017-07-05 23:39:00 Coffee NaN
....
[77 rows x 7 columns]
这意味着有 7 行具有完全相同的 Type、id 和 Time。 如果您想删除完全相同的行(合并所有列),这将产生所需的结果:
df=df.drop_duplicates()
此外:
dup=df.duplicated(subset=("id","Type","Time"))
返回一个 True/False 数组,指示行是否重复
0 False
1 False
2 False
3 False
4 False
5 False
6 True
7 False
如果您想知道 DataFrame 的哪些单个值是重复的,请使用:
dupl_val=df.apply(pd.Series.duplicated,axis=1)
id Duplicate 1 Duplicate 2 Total Duplicates Time Type Attribute
0 False False False False False False False
1 False False False False False False False
2 False False False False False False False
3 False False False False False False False
4 False False False True False False False
5 False False True True False False False
6 False False False True False False False
调用 pd.Series.duplicated 的原因是该方法应用于 DataFrame 的轴 1,这意味着每个单独的 DataFrame 列。 DataFrame 列是 Pandas Series 对象。
如果您不想删除行,而只是指出哪些值是重复的,请使用:
dupl_val=df.apply(pd.Series.duplicated,axis=1)
df=df.where(~dupl_val,"duplicate")
print(df)
id Duplicate 1 Duplicate 2 Total Duplicates \
0 121349100 NaN NaN NaN
1 121350610 NaN NaN NaN
2 124426041 NaN NaN NaN
3 124436734 NaN NaN NaN
4 124451775 1 NaN duplicate
5 124451775 1 duplicate duplicate
6 124451775 NaN 1 duplicate
Time Type Attribute
0 2017-04-19 18:08:00 Tea NaN
1 2017-04-19 18:08:00 Tea NaN
2 2017-05-05 12:21:00 Tea NaN
3 2017-04-25 15:20:00 Coffee NaN
4 2017-04-05 21:04:00 Coffee No
5 2017-06-05 07:38:00 Tea No
6 2017-04-05 21:04:00 Coffee NaN
编辑: 如果您只想将 Attribute 列设置为特殊值(我选择了“duplicate”),如果一行中的“id”、“Type”、“Time”值与另一行重复并且不想更改其余列的值,此代码应提供所需的结果:
frame=pd.read_excel(io=r"D:\xxxxx\test.xlsx")
df=pd.DataFrame(frame)
dup=df.duplicated(subset=("id","Type","Time"))
duplicate="duplicate"
for i in range(len(dup)):
if dup[i]==True:
df.loc[i,"Attribute"]=duplicate
print(df)
id Duplicate 1 Duplicate 2 Total Duplicates \
0 121349100 NaN NaN NaN
1 121350610 NaN NaN NaN
2 124426041 NaN NaN NaN
3 124436734 NaN NaN NaN
4 124451775 1.0 NaN 1.0
5 124451775 1.0 1.0 1.0
6 124451775 NaN 1.0 1.0
7 124463136 NaN NaN NaN
Time Type Attribute
0 2017-04-19 18:08:00 Tea NaN
1 2017-04-19 18:08:00 Tea NaN
2 2017-05-05 12:21:00 Tea NaN
3 2017-04-25 15:20:00 Coffee NaN
4 2017-04-05 21:04:00 Coffee No
5 2017-06-05 07:38:00 Tea No
6 2017-04-05 21:04:00 Coffee duplicate
7 2017-06-05 05:40:00 Coffee NaN
[85 rows x 7 columns]
您可以看到,第 6 行(= 原始 excel 文件中的第 8 行)包含第一个副本。在这种情况下,这是 excel 文件中第 6 行的副本。
编辑 2
在我的第二次编辑中,代码现在会将所有重复项(也是第一个)标记为“重复项”。此外,代码不再搜索所有三列(id、时间、类型),而是搜索(id 和时间)或(id 和类型)或(时间和类型)。因此这三个数的所有组合
dup=[df.duplicated(subset=(i),keep=False) for i in [("id","Type"),("id","Time"),("Time","Type")]]
duplicate="duplicate"
for i in range(len(dup)):
for j in range(len(dup[i])):
if dup[i][j]==True:
df.loc[j,"Attribute"]=duplicate
print(df)
|
id Duplicate 1 Duplicate 2 Total Duplicates \
0 121349100 NaN NaN NaN
1 121350610 NaN NaN NaN
2 124426041 NaN NaN NaN
3 124436734 NaN NaN NaN
4 124451775 1.0 NaN 1.0
5 124451775 1.0 1.0 1.0
6 124451775 NaN 1.0 1.0
Time Type Attribute
0 2017-04-19 18:08:00 Tea duplicate
1 2017-04-19 18:08:00 Tea duplicate
2 2017-05-05 12:21:00 Tea NaN
3 2017-04-25 15:20:00 Coffee NaN
4 2017-04-05 21:04:00 Coffee duplicate
5 2017-06-05 07:38:00 Tea No
6 2017-04-05 21:04:00 Coffee duplicate
有关此函数的更多信息,请阅读:drop_duplicates、duplicated,适用于 Series 和 DataFrame(主要区别在于,对于 Series,函数应用于单个值,而对于 DataFrame,它们分别应用于行以指定列的行)
【讨论】:
问题是我想在属性列中获取输出,我不想对现有列进行任何更改。 它确实部分工作,直到这一点我也想通了。我遇到的问题是:1)当有两个以上的重复项时,代码仅适用于一个并且仅针对其中一个重复项返回值。我想要的是该值应该针对两个重复项并且应该满足条件。2)它还显示 Duplicate 针对错误的值。我需要它来显示日期较旧的 ID 重复。 @PyNoob 1. 如果行中的值 (id,Time,Type) 之前曾出现过一次,则代码在 Attribure 列中重复“重复”。这也意味着第一行没有被标记为重复,而是第二、第三等等。您是否还希望第一行(值的第一次出现被标记为重复)? 2. 目前,如果 thr id 中的值,则代码仅标记重复。类型和时间列是相同的。我说得对吗,如果 id、Time 或 Type(意味着其中之一)重复,您还想将其标记为重复吗? 在我的第二次编辑中,代码现在会将所有重复项(也是第一个)标记为重复项。此外,代码不再搜索所有三列(id、时间、类型),而是搜索“id”或(id 和时间)或(id 和类型)。 不,我非常感谢您所做的事情,但您可能会再次查看我编辑的问题以便更好地理解。 @2Obe以上是关于如何根据python中的多个条件对excel文件进行重复数据删除?的主要内容,如果未能解决你的问题,请参考以下文章
Excel - UDF 函数,用于根据条件从多个工作表中获取 SUM 值