我有一个Excel文件(attached here)。我必须针对两个或更多重复的id重复数据删除。 重复数据删除的标准基于多种因素。
现在,我手动跟进重复数据删除的过程是:
我想做的是:
如果两个或多个ID根据特定条件重复,则在属性中设置否:
咖啡应该优于茶。如果我们有茶和咖啡 对于重复的id类型,我们在每个茶的属性中放入No 每个重复的ID。
如果每个重复ID都有一份茶和两份或更多咖啡 那么我们将根据时间(ID,对照剩余的咖啡)设置“否” 旧的时间戳应该是否。)
如果我们对每个重复的ID都有相同的类型,那么无论哪个ID 应该保留最新的时间和所有其他属性 应该是否。
如果我们对所有重复的ID都有相同的日期和相同的类型,那么我们 除了一个之外,它将随机设置为No。
注意:
重要问题: - 使用python是否可行或可行?
答案 0 :(得分:0)
我不知道我的问题是否正确,因此我将提供一些不同的方法。
如果要删除包含id,Type和Time相同值的所有行,可以使用以下命令:
bin
产生:
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)
这意味着有7行具有完全相同的Type,id和Time。 如果要删除完全相同的行(所有列都已合并),这将产生所需的结果:
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]
此外:
df=df.drop_duplicates()
返回一个True / False数组,指示行是否重复
dup=df.duplicated(subset=("id","Type","Time"))
如果您想知道DataFrame的哪些单个值是重复的,请使用:
0 False
1 False
2 False
3 False
4 False
5 False
6 True
7 False
调用pd.Series.duplicated的原因是此方法应用于DataFrame的轴1,这意味着每个单个DataFrame列。 DataFrame列是Pandas Series对象。
如果您不想删除行但只是指明哪些值是重复的,请使用:
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
修改强> 如果你只想将Attribute列设置为一个特殊值(我选择了“duplicate”)如果“id”,“Type”,一行中的“Time”值是另一行的重复,并且不想更改其余列的值,此代码应提供所需的结果:
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
你可以看到,第6行(=原始excel文件中的第8行)包含第一个副本。在这种情况下,这是excel文件中第6行的副本。
编辑2
在我的第二次编辑中,代码现在将所有重复项(也是第一项)标记为“重复项”。此外,代码不再搜索所有三列(id,Time,Type),而是(id和Time)OR(id和Type)OR(Time和Type)。因此,这三个coumns的所有组合
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]
|
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)
有关此函数的更多信息,请阅读:drop_duplicates,duplicated,系列和数据框架(主要区别在于,对于系列,函数应用于单个值,而对于DataFrame则应用它们分别到指定列的行)