pandas中的drop_duplicates无法正常工作?

14

我的代码的目的是导入两个Excel文件,对它们进行比较,并将差异打印到一个新的Excel文件中。

然而,在连接所有数据并使用drop_duplicates函数后,控制台接受了该代码。但是,在将其打印到新的Excel文件时,重复项仍然存在于当天。

我是否遗漏了什么?是否有什么正在使drop_duplicates函数无效?

我的代码如下:

import datetime
import xlrd
import pandas as pd
#identify excel file paths
filepath = r"excel filepath"
filepath2 = r"excel filepath2"
#read relevant columns from the excel files
df1 = pd.read_excel(filepath, sheetname="Sheet1", parse_cols= "B, D, G, O")
df2 = pd.read_excel(filepath2, sheetname="Sheet1", parse_cols= "B, D, F, J")
#merge the columns from both excel files into one column each respectively
df4 = df1["Exchange Code"] + df1["Product Type"] + df1["Product Description"] + df1["Quantity"].apply(str)
df5 = df2["Exchange"] + df2["Product Type"] + df2["Product Description"] + df2["Quantity"].apply(str)
#concatenate both columns from each excel file, to make one big column containing all the data
df = pd.concat([df4, df5])
#remove all whitespace from each row of the column of data
df=df.str.strip()
df=["".join(x.split()) for x in df] 
#convert the data to a dataframe from a series
df = pd.DataFrame({'Value': df}) 
#remove any duplicates
df.drop_duplicates(subset=None, keep="first", inplace=False)
#print to the console just as a visual aid
print(df)
#print the erroneous entries to an excel file
df.to_excel("Comparison19.xls") 

提示:阅读参数 df.drop_duplicates(subset=None, keep="first", inplace=False) - EdChum
从初步的观察来看,当你使用“drop_duplicates”方法时,你不会保存对“df”的修改。你需要将“inplace”设置为True,或者重新分配给相同的变量名。 - Alex
1
可能是[DataFrame.drop_duplicates和DataFrame.drop不删除行]的重复问题(https://dev59.com/QF8e5IYBdhLWcg3wfaYy)。 - IanS
7个回答

30

你使用了 inplace=False 参数,因此没有修改 df。你需要选择以下其中一种方式:

 df.drop_duplicates(subset=None, keep="first", inplace=True)
或者
 df = df.drop_duplicates(subset=None, keep="first", inplace=False)

将 inplace=False 替换为 inplace=True,成功了!谢谢 Keith。 - A. Blackmagic

15

我刚遇到了这个问题,但这不是解决方案。

文档中可能有提到 - 我承认我没有查看 - 但必须注意的是,只有在处理基于日期的唯一行时才需要遵循这个要求:'date'列必须按照日期格式进行格式化。

如果date数据是pandas的object dtype类型,则drop_duplicates将无法正常工作 - 需要先使用pd.to_datetime进行转换。


我尝试了这个,但它没有起作用:df['date_time']=pd.to_datetime(df.index)。我仍然得到非重复行被删除的结果。 - Wesley Kitlasten

12
如果您在DataFrame中使用DatetimeIndex,这将不起作用
df.drop_duplicates(subset=None, keep="first", inplace=True)

可以使用以下方法代替:
df = df[~df.index.duplicated()]

首先确保索引的数据类型不是object,而是datetime64,您可以使用df.index进行检查。您可能需要先将索引转换为正确的数据类型。
df = pd.to_datetime(df.index)

这对我不起作用。我尝试过使用df = df.set_index('date_time'),然后df = df [〜df.index.duplicated()]。但我仍然会丢掉不重复的行。 - Wesley Kitlasten
这也适用于具有日期时间部分的多索引数据帧。 - chazzmoney
2
@WesleyKitlasten 正如BAC83所评论的那样,请确保索引不是_object_类型,而是_datetime64_类型。您可能需要使用pd.to_datetime(df.index)先转换索引。 - psalt
适用于我 - 2个步骤:1- 确保您的索引是 pd.to_datetime(df.index) 2- 使用 df = df[~df.index.duplicated()] - ArmandduPlessis

11

可能会对未来有帮助。

我有一个日期列,尝试删除重复项但没有成功。如果保持该列的日期格式对进一步操作不重要,则可以将该列从对象类型转换为字符串类型。

df = df.astype('str')

然后我执行了 @Keith 的答案。

df = df.drop_duplicates(subset=None, keep="first", inplace=False)

1
非常感谢!之前一直苦恼为什么还会出现重复记录,但是通过将日期时间字段转换为df ['x'] = df ['x'].dt.date解决了问题。这个方法很有效,而且不需要将其转换为字符串。如果没有被指出来,我可能不会测试这个方法。再次感谢! - thomassantosh
1
很高兴你解决了这个问题 :)!我同意日期变量的困扰,所以很乐意分享想法,因为我认为日期是编码中比较棘手的方面之一。 - Wizhi
这个救了我。我使用了 df.applymap(str) 但是结果当然相同。 - Martin H
成功了!谢谢,你救了我一天!!! - Rodrigo Serzedello
连ChatGPT都不知道这个... (-: 谢谢! - cs0815

5

使用inplace=False告诉pandas返回一个新的数据框,其中重复项已被删除,因此您需要将其分配回df

使用inplace=False会返回一个去除了重复项的新数据框,需要将其赋值给df变量:
df = df.drop_duplicates(subset=None, keep="first", inplace=False)

或者使用inplace=True参数告诉 Pandas 在当前数据框中删除重复项。

df.drop_duplicates(subset=None, keep="first", inplace=True)

1

不确定这是否是一个好的地方来放置它。但我最近学到,.drop_duplicates()必须在所有子集中都有匹配项才能删除一行。

因此,为了仅基于一个值删除多个值,我使用了这段代码:

no_duplicates_df = df.drop_duplicates(subset=['email'], keep="first", inplace=False)                     # Delete duplicates in email
no_duplicates_df = no_duplicates_df.drop_duplicates(subset=['phonenumber'], keep="first", inplace=False) # Delete duplicates in phonenumber

0

我曾遇到同样的问题,但原因不同。

在将一个数据框追加到另一个数据框之后,我想根据 id(整数)进行去重。然而,追加操作将该列的类型更改为浮点型,并且无法正常工作(请参见https://github.com/pydata/pandas/issues/6485)。在运行 drop_duplicates 之前,我通过运行以下命令来解决它:

df = df.astype({'id': 'int64'})


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接