当前位置:首页 > 文章列表 > 文章 > python教程 > Python数据去重方法与drop\_duplicates使用详解

Python数据去重方法与drop\_duplicates使用详解

2025-07-09 11:04:18 0浏览 收藏

从现在开始,努力学习吧!本文《Python数据去重方法及drop\_duplicates参数详解》主要讲解了等等相关知识点,我会在golang学习网中持续更新相关的系列文章,欢迎大家关注并积极留言建议。下面就先一起来看一下本篇正文内容吧,希望能帮到你!

数据去重在数据分析中至关重要,因为它确保了数据的准确性、减少资源浪费并提升数据质量。1. 使用Pandas库中的drop_duplicates()方法是最常见且强大的工具;2. 该方法支持通过subset参数指定去重的列,默认检查所有列;3. keep参数控制保留重复项的方式,可选'first'(默认)、'last'或False(删除所有重复项);4. inplace参数允许直接在原数据上操作;5. 去重常用于移除完全重复记录、提取最新状态或找出唯一记录等场景,结合排序等操作能更灵活应对实际需求。

怎样用Python实现数据去重?drop_duplicates参数详解

用Python实现数据去重,最常用也最强大的工具无疑是Pandas库里的drop_duplicates()方法。它能高效地识别并移除DataFrame或Series中重复的行或值,让你的数据变得更干净、分析结果更可靠。在我看来,这是数据清洗流程里最基础也最关键的一步,少了它,很多后续分析都可能跑偏。

怎样用Python实现数据去重?drop_duplicates参数详解

解决方案

要使用drop_duplicates(),首先你需要有一个Pandas DataFrame或Series。这个方法提供了几个参数,让你能灵活控制去重逻辑。

我们先从一个简单的例子开始:

怎样用Python实现数据去重?drop_duplicates参数详解
import pandas as pd
import numpy as np

# 构造一个示例DataFrame
data = {
    'ID': [1, 2, 3, 1, 4, 2, 5],
    'Name': ['Alice', 'Bob', 'Charlie', 'Alice', 'David', 'Bob', 'Eve'],
    'Score': [85, 90, 78, 85, 92, 90, 88],
    'City': ['NY', 'LA', 'SF', 'NY', 'CHI', 'LA', 'MIA']
}
df = pd.DataFrame(data)
print("原始DataFrame:")
print(df)

# 最简单的去重:移除所有列都相同的重复行
df_deduplicated_all = df.drop_duplicates()
print("\n去重后 (所有列都相同才算重复):")
print(df_deduplicated_all)

# 针对特定列去重,例如只看'ID'和'Name'是否重复
# 默认保留第一次出现的重复项
df_deduplicated_subset = df.drop_duplicates(subset=['ID', 'Name'])
print("\n去重后 (只看'ID'和'Name'是否重复):")
print(df_deduplicated_subset)

# 去重并保留最后一次出现的重复项
df_deduplicated_keep_last = df.drop_duplicates(subset=['ID', 'Name'], keep='last')
print("\n去重后 (只看'ID'和'Name'是否重复, 保留最后出现的):")
print(df_deduplicated_keep_last)

# 去重并删除所有重复项(即如果出现过重复,所有重复项都会被删除)
df_deduplicated_keep_false = df.drop_duplicates(subset=['ID', 'Name'], keep=False)
print("\n去重后 (只看'ID'和'Name'是否重复, 删除所有重复项):")
print(df_deduplicated_keep_false)

# 直接在原DataFrame上进行去重操作,不创建新的DataFrame
df_inplace = df.copy() # 先复制一份,以免影响原始df
df_inplace.drop_duplicates(inplace=True)
print("\n原地去重后的DataFrame (df_inplace):")
print(df_inplace)

drop_duplicates()方法的关键参数包括:

  • subset: 这是一个列表,指定在哪些列上检查重复项。如果省略,则检查所有列。
  • keep: 决定保留哪个重复项。
    • 'first' (默认): 保留第一次出现的重复项。
    • 'last': 保留最后一次出现的重复项。
    • False: 删除所有重复项,即如果一个行是重复的,那么所有与其重复的行都会被删除。
  • inplace: 一个布尔值,如果为True,则在原始DataFrame上进行操作并返回None;如果为False (默认),则返回一个去重后的新DataFrame。

为什么数据去重在数据分析中至关重要?

说实话,数据去重的重要性常常被低估,或者说,很多人只有在分析结果出现明显偏差时,才会回头审视是不是数据源头就有问题。在我看来,这就像盖房子,地基不稳,上层建筑再华丽也可能倾斜。重复数据会带来一系列麻烦,远不止是占用存储空间那么简单。

怎样用Python实现数据去重?drop_duplicates参数详解

首先,它直接影响统计结果的准确性。比如,你正在分析用户行为,如果一个用户ID因为某种系统错误被记录了两次,那么你在计算活跃用户数、平均购买次数时,结果就会被虚增。这会导致你对业务的判断失真,甚至做出错误的决策。一个用户被算成两个,那你的转化率、留存率可能就没那么好看了,或者说,你以为的数据规模是真实的,但实际上却掺了水分。

其次,重复数据会浪费计算资源和时间。在处理大规模数据集时,多余的数据意味着更多的内存占用和更长的处理时间。无论是进行复杂的数据转换、模型训练还是可视化,每一步都会因为这些“冗余”而变得更慢。想象一下,你训练一个机器学习模型,如果训练集里有大量重复样本,模型可能会过度拟合这些重复数据,导致泛化能力下降,这可不是我们想看到的。

最后,从数据质量和信任度来看,干净的数据是任何分析项目的基础。如果你给出的报告或模型,其背后数据充斥着重复项,那么它的可信度会大打折扣。所以,数据去重不仅仅是技术操作,更是数据治理和保障数据质量的重要环节。它确保了我们所看到、所分析的数据,是真实、独立且有意义的。

理解drop_duplicates()subsetkeep参数

drop_duplicates()的强大之处,很大程度上就体现在它对subsetkeep这两个参数的灵活控制上。它们决定了“重复”的定义以及“保留”的策略,这在实际工作中至关重要。

先说subset。默认情况下,如果你不指定subsetdrop_duplicates()会检查DataFrame中所有列的值是否都完全相同。只有当两行在所有列上的值都一模一样时,才会被认为是重复的。这在很多情况下是合理的,比如你只想找出完全相同的记录。

但更多时候,我们对“重复”的定义是基于部分列的。例如,一个用户可能在不同时间购买了不同的商品,所以他的所有购买记录行不可能完全相同。但如果你想找出“重复的用户”,那么你可能只需要看UserID这一列。如果UserID相同,就认为这是同一个用户的记录。

# 假设我们有一个订单记录,想找出哪些用户是重复的(即出现多次)
order_data = {
    'OrderID': [101, 102, 103, 104, 105, 106],
    'UserID': ['A001', 'B002', 'A001', 'C003', 'B002', 'A001'],
    'Product': ['Laptop', 'Mouse', 'Keyboard', 'Monitor', 'Laptop', 'Mouse'],
    'Price': [1200, 25, 80, 300, 1000, 30]
}
df_orders = pd.DataFrame(order_data)
print("原始订单数据:")
print(df_orders)

# 找出所有不重复的UserID(即每个UserID只出现一次)
unique_users_df = df_orders.drop_duplicates(subset=['UserID'])
print("\n按UserID去重后的用户列表 (默认保留第一次出现):")
print(unique_users_df)

这里,subset=['UserID']告诉Pandas,只要UserID这一列的值相同,就视为重复。至于ProductPrice列的值是否相同,则不予考虑。这非常实用,比如你只想获取一个不重复的用户ID列表,而不在乎他们具体买了什么。

接下来是keep参数。这真的是一个需要仔细考量的地方,因为它直接决定了哪条数据被留下,哪条被移除。

  • keep='first' (默认): 这是最常见的选择。它会保留第一次出现的重复项。比如你有三条记录:A, B, A' (A和A'在subset列上是重复的,A先出现,A'后出现),那么A会被保留,A'会被删除。这适用于你认为“最早记录”或“原始记录”最有意义的场景。
  • keep='last': 这会保留最后一次出现的重复项。在上面的例子中,A'会被保留,A会被删除。这在某些情况下非常有用,比如你有一个用户状态的历史记录,你可能只想保留最新的状态。
  • keep=False: 这个选项则更为激进。它会删除所有重复项。也就是说,如果A和A'是重复的,那么A和A'都会被删除。只有那些在subset列上是完全唯一的行才会被保留。这适用于你只想找出那些“绝对唯一”的记录,任何一点重复都不能容忍的场景。
# 假设我们有员工打卡记录,有时员工会重复打卡,我们想保留最新的记录
checkin_data = {
    'EmployeeID': ['E001', 'E002', 'E001', 'E003', 'E002'],
    'CheckInTime': ['2023-10-26 08:00', '2023-10-26 08:05', '2023-10-26 08:10', '2023-10-26 08:15', '2023-10-26 08:20']
}
df_checkin = pd.DataFrame(checkin_data)
# 确保时间列是datetime类型,方便排序
df_checkin['CheckInTime'] = pd.to_datetime(df_checkin['CheckInTime'])
print("原始打卡记录:")
print(df_checkin)

# 先按时间排序,确保“最后一次”真的是最新的
df_checkin_sorted = df_checkin.sort_values(by='CheckInTime', ascending=True)

# 保留每个员工的最新打卡记录
latest_checkins = df_checkin_sorted.drop_duplicates(subset=['EmployeeID'], keep='last')
print("\n每个员工的最新打卡记录:")
print(latest_checkins)

# 如果我们想找出那些只打卡一次的员工(即没有重复记录的)
unique_only_checkins = df_checkin.drop_duplicates(subset=['EmployeeID'], keep=False)
print("\n只打卡一次的员工记录:")
print(unique_only_checkins)

选择keep参数时,真的需要结合你的业务逻辑和数据特点来判断。没有绝对的“正确”答案,只有最适合你当前分析目标的策略。

结合实际场景,如何灵活运用drop_duplicates()

drop_duplicates()在实际数据处理中简直是万金油,它的灵活运用能解决很多看似复杂的问题。这里我分享几个常见的场景和我的思考。

场景一:移除完全相同的冗余记录

这是最直接的用法,通常用于导入数据后初步清洗。比如你从某个数据库导出了一批日志,由于系统故障或者多次导出合并,可能存在完全相同的日志条目。这时候,不带任何参数的drop_duplicates()就能派上用场。

# 假设日志数据
log_data = {
    'Timestamp': ['2023-10-26 10:00:00', '2023-10-26 10:01:00', '2023-10-26 10:00:00', '2023-10-26 10:02:00'],
    'EventType': ['Login', 'Click', 'Login', 'Logout'],
    'UserID': ['userA', 'userB', 'userA', 'userC']
}
df_logs = pd.DataFrame(log_data)
print("原始日志数据:")
print(df_logs)

df_logs_cleaned = df_logs.drop_duplicates()
print("\n完全去重后的日志:")
print(df_logs_cleaned)

这里,('2023-10-26 10:00:00', 'Login', 'userA')这条记录出现了两次,第一次去重后它只剩一条。

场景二:基于部分关键字段去重,保留“最新”或“最旧”状态

这在处理用户资料、商品信息等主数据时非常常见。比如,你有一个用户资料表,用户可以多次更新他们的地址。你可能只关心他们当前的最新地址,而不是所有的历史地址。

# 用户地址更新记录
user_address_data = {
    'UserID': ['U001', 'U002', 'U001', 'U003', 'U002'],
    'Address': ['Street A', 'Street B', 'Street C', 'Street D', 'Street E'],
    'UpdateTime': ['2023-01-01', '2023-02-01', '2023-03-01', '2023-04-01', '2023-05-01']
}
df_address = pd.DataFrame(user_address_data)
df_address['UpdateTime'] = pd.to_datetime(df_address['UpdateTime']) # 转换为日期时间类型

print("原始用户地址记录:")
print(df_address)

# 找出每个用户的最新地址
# 关键步骤:先按UpdateTime排序,确保最新的记录在后面
df_address_sorted = df_address.sort_values(by='UpdateTime', ascending=True)
latest_addresses = df_address_sorted.drop_duplicates(subset=['UserID'], keep='last')

print("\n每个用户的最新地址:")
print(latest_addresses)

这里,我们先对数据按UpdateTime升序排序,这样最新的记录就会在重复项的最后面。然后,使用drop_duplicates(subset=['UserID'], keep='last'),就能精准地提取出每个用户的最新地址了。这种先排序再去重的模式,在处理带有时间戳的数据时,是极其常用的技巧。

场景三:找出“真正独特”的记录,即任何重复都不保留

有时候,你可能想找出那些在某个维度上是“独一无二”的实体,任何出现过一次以上的情况,你都想剔除。这就像在班级里找“独生子女”,只要有兄弟姐妹的,都不算。

# 假设我们有一个产品销售记录,想找出那些只被购买过一次的产品ID
sales_data = {
    'ProductID': ['P001', 'P002', 'P001', 'P003', 'P004', 'P002'],
    'SaleDate': ['2023-10-01', '2023-10-02', '2023-10-03', '2023-10-04', '2023-10-05', '2023-10-06']
}
df_sales = pd.DataFrame(sales_data)
print("原始销售记录:")
print(df_sales)

# 找出只被购买过一次的产品
unique_products_only = df_sales.drop_duplicates(subset=['ProductID'], keep=False)
print("\n只被购买过一次的产品记录:")
print(unique_products_only)

在这个例子中,P001P002都出现了不止一次,所以它们都被keep=False移除了。只有P003P004因为只出现了一次,被保留了下来。

在处理非常大的数据集时,drop_duplicates()的性能通常是很好的,因为它在底层是用C优化的。但如果你发现性能瓶颈,可以考虑在去重前,先对数据进行必要的筛选或抽样,减少处理的数据量。总的来说,理解并灵活运用drop_duplicates()的参数,能让你在数据清洗的道路上事半功倍。

以上就是本文的全部内容了,是否有顺利帮助你解决问题?若是能给你带来学习上的帮助,请大家多多支持golang学习网!更多关于文章的相关知识,也可关注golang学习网公众号。

豆包AI卡顿?实用优化技巧分享豆包AI卡顿?实用优化技巧分享
上一篇
豆包AI卡顿?实用优化技巧分享
通灵义码操作技巧全解析
下一篇
通灵义码操作技巧全解析
查看更多
最新文章
查看更多
课程推荐
  • 前端进阶之JavaScript设计模式
    前端进阶之JavaScript设计模式
    设计模式是开发人员在软件开发过程中面临一般问题时的解决方案,代表了最佳的实践。本课程的主打内容包括JS常见设计模式以及具体应用场景,打造一站式知识长龙服务,适合有JS基础的同学学习。
    542次学习
  • GO语言核心编程课程
    GO语言核心编程课程
    本课程采用真实案例,全面具体可落地,从理论到实践,一步一步将GO核心编程技术、编程思想、底层实现融会贯通,使学习者贴近时代脉搏,做IT互联网时代的弄潮儿。
    509次学习
  • 简单聊聊mysql8与网络通信
    简单聊聊mysql8与网络通信
    如有问题加微信:Le-studyg;在课程中,我们将首先介绍MySQL8的新特性,包括性能优化、安全增强、新数据类型等,帮助学生快速熟悉MySQL8的最新功能。接着,我们将深入解析MySQL的网络通信机制,包括协议、连接管理、数据传输等,让
    497次学习
  • JavaScript正则表达式基础与实战
    JavaScript正则表达式基础与实战
    在任何一门编程语言中,正则表达式,都是一项重要的知识,它提供了高效的字符串匹配与捕获机制,可以极大的简化程序设计。
    487次学习
  • 从零制作响应式网站—Grid布局
    从零制作响应式网站—Grid布局
    本系列教程将展示从零制作一个假想的网络科技公司官网,分为导航,轮播,关于我们,成功案例,服务流程,团队介绍,数据部分,公司动态,底部信息等内容区块。网站整体采用CSSGrid布局,支持响应式,有流畅过渡和展现动画。
    484次学习
查看更多
AI推荐
  • AI边界平台:智能对话、写作、画图,一站式解决方案
    边界AI平台
    探索AI边界平台,领先的智能AI对话、写作与画图生成工具。高效便捷,满足多样化需求。立即体验!
    353次使用
  • 讯飞AI大学堂免费AI认证证书:大模型工程师认证,提升您的职场竞争力
    免费AI认证证书
    科大讯飞AI大学堂推出免费大模型工程师认证,助力您掌握AI技能,提升职场竞争力。体系化学习,实战项目,权威认证,助您成为企业级大模型应用人才。
    370次使用
  • 茅茅虫AIGC检测:精准识别AI生成内容,保障学术诚信
    茅茅虫AIGC检测
    茅茅虫AIGC检测,湖南茅茅虫科技有限公司倾力打造,运用NLP技术精准识别AI生成文本,提供论文、专著等学术文本的AIGC检测服务。支持多种格式,生成可视化报告,保障您的学术诚信和内容质量。
    508次使用
  • 赛林匹克平台:科技赛事聚合,赋能AI、算力、量子计算创新
    赛林匹克平台(Challympics)
    探索赛林匹克平台Challympics,一个聚焦人工智能、算力算法、量子计算等前沿技术的赛事聚合平台。连接产学研用,助力科技创新与产业升级。
    617次使用
  • SEO  笔格AIPPT:AI智能PPT制作,免费生成,高效演示
    笔格AIPPT
    SEO 笔格AIPPT是135编辑器推出的AI智能PPT制作平台,依托DeepSeek大模型,实现智能大纲生成、一键PPT生成、AI文字优化、图像生成等功能。免费试用,提升PPT制作效率,适用于商务演示、教育培训等多种场景。
    522次使用
微信登录更方便
  • 密码登录
  • 注册账号
登录即同意 用户协议隐私政策
返回登录
  • 重置密码