查看全课大纲(第 46 / 101 节)
- 1.数据分析基本概念
- 2.学习数据分析的一般路线
- 3.数据分析的流程
- 4.数据类型
- 5.环境部署(1)
- 6.环境部署(2)
- 7.课程介绍
- 8.TXT文件操作
- 9.JSON文件操作
- 10.CSV文件操作
- 11.Excel文件操作
- 12.数据库及SQL常用语法
- 13.数据库基本操作
- 14.数据库多表连接
- 15.实战:欧洲职业足球数据库分析
- 16.爬虫简介
- 17.URL管理模块
- 18.网页下载模块
- 19.网页解析模块(1)
- 20.网页解析模块(2)
- 21.Scrapy简介
- 22.Scrapy使用步骤(1)
- 23.Scrapy使用步骤(2)
- 24.Scrapy使用步骤(3)
- 25.Scrapy使用步骤(4)
- 26.实战:获取国内城市空气质量指数数据
- 27.NumPy和SciPy介绍
- 28.多维数组
- 29.多维数组操作
- 30.NumPy的常用方法
- 31.向量化介绍
- 32.向量化及通用函数
- 33.实战:2016美国大选分析
- 34.数据结构-Series
- 35.数据结构-DataFrame
- 36.数据结构-Index
- 37.Series的索引操作
- 38.DataFrame的索引操作
- 39.索引操作总结
- 40.运算与对齐
- 41.函数应用操作(1) -- map
- 42.函数应用操作 (2) -- apply applymap
- 43.文件读写操作
- 44.排序操作
- 45.数据清洗--处理缺失数据
- 46.数据清洗--处理重复数据
- 47.数据清洗--替换数据
- 48.常用统计方法(1) -- describe quantile
- 49.常用统计方法(2) -- sum mean median count
- 50.常用统计方法(3) -- max min idxmax idxmin
- 51.常用统计方法(4) -- mad var std cumsum
- 52.实战:全球食品数据分析
- 53.层级索引
- 54.分组与聚合介绍
- 55.分组操作(1) -- GroupBy对象及常用聚合操作
- 56.分组操作(2) -- 自定义分组及聚合操作
- 57.透视表介绍
- 58.透视表操作
- 59.数据规整(1) -- 数据合并concat
- 60.数据规整(2) -- 数据连接merge
- 61.数据重构(3) -- 数据重构stack unstack
- 62.实战:互联网电影资料库分析
- 63.探索性数据分析EDA介绍
- 64.EDA的目的
- 65.EDA常用工具
- 66.Matplotlib绘图基本介绍
- 67.Matplotlib画布
- 68.散点图和柱状图的绘制
- 69.直方图的绘制
- 70.矩阵绘图
- 71.子图的使用
- 72.Matplotlib颜色、标记、线型
- 73.Matplotlib坐标刻度、标签、图例、标题
- 74.Seaborn介绍
- 75.数据集分布可视化(1) -- 单变量分布、双变量分布
- 76.数据集分布可视化(2) -- 变量关系可视化
- 77.类别数据可视化 -- 类别散布图、类别内数据分布、类别内统计图
- 78.交互式数据可视化工具Bokeh介绍
- 79.Bokeh绘制散点图、柱状图、盒子图、弦图
- 80.Bokeh绘制常用图形元素
- 81.3D绘图 -- mplot3d
- 82.3D曲线可视化
- 83.3D散点图可视化
- 84.3D柱状图可视化
- 85.Pandas绘图
- 86.实战:Lending Club借贷数据探索性分析及可视化
- 87.机器学习介绍及应用场景
- 88.机器学习建模介绍 (1) -- 分类
- 89.机器学习建模介绍 (2) -- 回归
- 90.机器学习建模介绍 (3) -- 聚类
- 91.机器学习分类
- 92.机器学习工具scikit-learn
- 93.使用scikit-learn的流程
- 94.数据集准备及划分
- 95.模型选择
- 96.数据预处理及特征工程
- 97.过拟合与欠拟合
- 98.模型调参介绍
- 99.模型调参方法
- 100.模型测试及评价
- 101.实战:通过移动设备行为数据预测性别和年龄
数据清洗--处理重复数据
约 5 分钟
重复数据的识别与处理
小象实战讲义 · Python数据分析实战
在上一节我们学习了如何处理缺失值,这是数据清洗的第一步。本节我们将继续数据清洗的另一个核心任务:识别并处理重复数据。重复数据会干扰统计分析的准确性,导致模型训练结果偏差。学完本节,你将掌握使用Pandas快速定位和删除重复记录的方法。
💡 核心导读
- 判断重复:使用
duplicated()方法,返回布尔型Series,标记每行是否为重复行。 - 指定列判断:通过
subset参数,可以只针对某些列的组合判断重复性。 - 删除重复:使用
drop_duplicates()方法,可以删除重复行。 - 删除策略:通过
keep参数控制保留哪一条重复记录(首次出现、最后一次出现或全部删除)。
1. 识别重复数据
处理重复数据的第一步是判断数据中是否存在重复记录。Pandas提供了 duplicated() 方法来完成这个任务。它会逐行检查,如果某一行与它之前的某一行内容完全相同,则将该行标记为重复行(True),否则为不重复(False)。
import pandas as pd
# 构造示例数据
data = pd.DataFrame({
'age': [28, 31, 27, 28],
'gender': ['M', 'M', 'M', 'F'],
'surname': ['Liu', 'Li', 'Chen', 'Liu']
})
print("原始数据:")
print(data)原始数据:
age gender surname
0 28 M Liu
1 31 M Li
2 27 M Chen
3 28 F Liu现在,我们使用 duplicated() 方法判断整行是否完全重复。
import pandas as pd
# 构造示例数据(自包含)
data = pd.DataFrame({
'age': [28, 31, 27, 28],
'gender': ['M', 'M', 'M', 'F'],
'surname': ['Liu', 'Li', 'Chen', 'Liu']
})
# 判断整行是否重复
duplicated_all = data.duplicated()
print("整行重复判断结果:")
print(duplicated_all)整行重复判断结果:
0 False
1 False
2 False
3 False
dtype: bool结果显示所有行都是 False,因为我们的数据中没有完全相同的两行(注意,第0行和第3行虽然年龄和姓氏相同,但性别不同)。
2. 基于指定列判断重复
在实际分析中,我们可能只关心部分列是否重复。例如,在人员信息中,我们可能认为“年龄”和“姓氏”相同就属于重复记录(暂不考虑重名情况)。这时可以使用 subset 参数来指定需要检查的列。
import pandas as pd
# 构造示例数据(自包含)
data = pd.DataFrame({
'age': [28, 31, 27, 28],
'gender': ['M', 'M', 'M', 'F'],
'surname': ['Liu', 'Li', 'Chen', 'Liu']
})
# 只判断‘age’和‘surname’两列是否重复
duplicated_subset = data.duplicated(subset=['age', 'surname'])
print("指定列(age, surname)重复判断结果:")
print(duplicated_subset)指定列(age, surname)重复判断结果:
0 False
1 False
2 False
3 True
dtype: bool这次我们看到第3行(索引3)被标记为 True。因为第3行(年龄28,姓氏Liu)与第0行(年龄28,姓氏Liu)在指定的两列上内容相同。duplicated() 方法默认将后出现的行标记为重复行。
3. 删除重复数据
识别出重复数据后,下一步就是删除它们。Pandas的 drop_duplicates() 方法可以帮我们过滤掉重复行。这个方法同样支持 subset 参数,并且多了一个关键的 keep 参数,用于控制删除重复行时的保留策略。
3.1 默认删除(保留首次出现)
keep 参数默认为 'first',即保留第一次出现的行,删除后面出现的重复行。
import pandas as pd
# 构造示例数据(自包含)
data = pd.DataFrame({
'age': [28, 31, 27, 28],
'gender': ['M', 'M', 'M', 'F'],
'surname': ['Liu', 'Li', 'Chen', 'Liu']
})
# 默认删除重复行(keep='first'),基于‘age’和‘surname’列
data_dropped_first = data.drop_duplicates(subset=['age', 'surname'])
print("删除重复行(保留首次出现):")
print(data_dropped_first)删除重复行(保留首次出现):
age gender surname
0 28 M Liu
1 31 M Li
2 27 M Chen可以看到,索引为3的行(后出现的重复行)被删除了,保留了索引为0的原始行。
3.2 保留最后一次出现
如果将 keep 参数设置为 'last',则会保留最后一次出现的行,删除之前出现的重复行。
import pandas as pd
# 构造示例数据(自包含)
data = pd.DataFrame({
'age': [28, 31, 27, 28],
'gender': ['M', 'M', 'M', 'F'],
'surname': ['Liu', 'Li', 'Chen', 'Liu']
})
# 删除重复行,但保留最后一次出现的(keep='last')
data_dropped_last = data.drop_duplicates(subset=['age', 'surname'], keep='last')
print("删除重复行(保留最后出现):")
print(data_dropped_last)删除重复行(保留最后出现):
age gender surname
1 31 M Li
2 27 M Chen
3 28 F Liu这次,索引为0的行(第一次出现的重复行)被删除了,保留了索引为3的行。请注意,性别信息也发生了变化(从M变成了F),因为保留的是最后一条记录。
3.3 删除所有重复行(不保留)
还有一种情况,如果我们希望将所有重复的行都删除,只保留那些在所有指定列上完全唯一的行,可以将 keep 参数设置为 False。
import pandas as pd
# 构造一个包含多组重复数据的例子
data_example = pd.DataFrame({
'age': [28, 31, 27, 28, 28, 31],
'gender': ['M', 'M', 'M', 'F', 'M', 'M'],
'surname': ['Liu', 'Li', 'Chen', 'Liu', 'Liu', 'Li']
})
print("新示例数据:")
print(data_example)
# 删除所有在‘age’和‘surname’上重复的行
data_unique = data_example.drop_duplicates(subset=['age', 'surname'], keep=False)
print("\n删除所有重复行后(只保留唯一组合):")
print(data_unique)新示例数据:
age gender surname
0 28 M Liu
1 31 M Li
2 27 M Chen
3 28 F Liu
4 28 M Liu
5 31 M Li
删除所有重复行后(只保留唯一组合):
age gender surname
2 27 M Chen在这个例子中,年龄和姓氏的组合(28, Liu)和(31, Li)都出现了多次,因此这些行被全部删除,只留下了唯一组合(27, Chen)对应的行。
本章小结
处理重复数据是数据清洗中至关重要的一环。通过本节学习,你应该掌握了:
- 判断重复:使用
data.duplicated(subset=列列表)来识别重复行。 - 删除重复:使用
data.drop_duplicates(subset=列列表, keep=策略)来清理数据。 - 策略选择:理解
keep参数('first','last',False)的含义,根据业务需求决定保留哪条记录。
📋 行动清单
- 对你手头的数据集尝试使用
duplicated()方法,查看是否存在重复记录。 - 思考你的业务场景中,哪些列的组合能唯一标识一条记录,并用
subset参数进行针对性去重。 - 练习使用不同的
keep参数,观察删除重复行后数据的变化。
📝 动手练一练
- 概念辨析:
data.duplicated()和data.drop_duplicates()返回的对象类型分别是什么?如果对原始DataFrame执行data.drop_duplicates(inplace=True),会有什么效果?
👉 点击查看参考答案
data.duplicated()返回的是一个布尔型的 Series,长度与原DataFrame行数相同,标记每行是否为重复行。data.drop_duplicates()返回的是一个新的 DataFrame,是删除重复行后的结果。- 如果设置
inplace=True,则操作会直接在原始的dataDataFrame 上修改,不会返回新的DataFrame。例如data.drop_duplicates(inplace=True)后,data本身就被去重了。
- 动手实践:假设你有一个销售记录DataFrame,包含
order_id(订单ID),product_id(产品ID),sale_date(销售日期)三列。业务上认为同一产品在同一天只能算一次有效销售(忽略订单ID)。请写出代码,找出那些product_id和sale_date组合重复的记录,并删除它们(保留第一次出现的记录)。
👉 点击查看参考答案
import pandas as pd
# 模拟销售数据
sales_data = pd.DataFrame({
'order_id': [1001, 1002, 1003, 1004, 1005],
'product_id': ['P001', 'P002', 'P001', 'P003', 'P001'],
'sale_date': ['2023-10-01', '2023-10-01', '2023-10-01', '2023-10-02', '2023-10-01']
})
print("原始销售数据:")
print(sales_data)
# 找出 product_id 和 sale_date 重复的记录
duplicate_mask = sales_data.duplicated(subset=['product_id', 'sale_date'])
print("\n重复记录标记:")
print(duplicate_mask)
# 删除重复,保留第一次出现
cleaned_sales = sales_data.drop_duplicates(subset=['product_id', 'sale_date'])
print("\n去重后的数据:")
print(cleaned_sales)原始销售数据:
order_id product_id sale_date
0 1001 P001 2023-10-01
1 1002 P002 2023-10-01
2 1003 P001 2023-10-01
3 1004 P003 2023-10-02
4 1005 P001 2023-10-01
重复记录标记:
0 False
1 False
2 True
3 False
4 True
dtype: bool
去重后的数据:
order_id product_id sale_date
0 1001 P001 2023-10-01
1 1002 P002 2023-10-01
3 1004 P003 2023-10-02产品P001在2023-10-01这一天出现了三次(订单1001,1003,1005)。去重后只保留了第一次出现的记录(订单1001)。
—— 小象教研组
配套资料 · 直接下载
课件、代码、数据集等配套资料全部免费,点击即可直接下载,无需分享或解锁。
- 下载本节课件:数据清洗--处理重复数据PDF · 180KB
- 下载全套课件打包(第1-5章)ZIP · 12.8MB
- 下载全套课件打包(第6-8章)ZIP · 15MB
- 下载实战数据集:AppleStore 应用商城分析ZIP · 329KB
- 下载实战数据集:女性服装电商分析ZIP · 2.8MB
- 下载Python 数据分析环境搭建指南PDF · 2MB
- 下载Scrapy 安装教程PDF · 12.7MB
- 下载附加实战项目:AppleStore 应用商城数据分析ZIP · 0.3MB · ipynb + CSV 数据
- 下载附加实战项目:银行电话营销数据分析ZIP · 0.4MB · ipynb + CSV 数据
- 下载附加实战项目:女性服装电商评论数据分析ZIP · 2.7MB · ipynb + CSV 数据
- 下载附加实战项目:美国化学学会杂志数据分析ZIP · 34.2MB · ipynb + SQLite 数据库