Python 数据分析入门:一文搞懂数据集成与重复数据处理(附 Pandas 实战)
适合人群:Python 初学者 / 数据分析入门 / 数据预处理学习者 / 教学案例分享
在真实的数据分析工作中,我们很少只面对一张"干净完整"的表。
更多时候,数据会来自多个系统、多个部门、多个文件。
比如同一批学生的数据,可能分别来自:
- 教务系统:成绩、补考信息
- 学工系统:考勤、纪律信息
- 实训系统:项目成绩、实训表现
- 问卷系统:学习态度、职业规划
这时候就会遇到很多非常实际的问题:
- 两张表里的字段名不一样,怎么对应?
- 同一个学生在两张表里是不是同一个人?
- 同一个学生为什么会出现两条记录?
- 不同系统里的同一字段值不一致,该听谁的?
这些问题,本质上都属于:
数据集成与重复数据处理
本文将通过一个"学生多来源数据合并"的案例,带你理解:
- 什么是数据集成
- 为什么数据不能简单拼接
- 数据集成时最常见的几个问题
- 如何使用
Pandas合并数据、检测重复值、删除重复值 - 如何初步处理字段不一致和数据冲突问题
一、为什么真实数据不能直接"拼表"?
很多初学者拿到两张表后,第一反应是:
"把它们合起来不就行了?"
但真正做起来,会发现事情没那么简单。
例如下面两张表:
教务系统数据
python
import pandas as pd
df_score = pd.DataFrame({
'student_id': ['2023001', '2023002', '2023003', '2023004'],
'姓名': ['张三', '李四', '王五', '赵六'],
'数学成绩': [88, 76, 90, 82]
})
print(df_score)
学工系统数据
python
df_attendance = pd.DataFrame({
'stu_no': ['2023001', '2023002', '2023002', '2023005'],
'姓名': ['张三', '李四', '李四', '钱七'],
'考勤次数': [20, 18, 18, 19]
})
print(df_attendance)
光看这两张表,就已经能发现几个问题:
- 一张表里叫
student_id,另一张表里叫stu_no - 李四在第二张表里出现了两次
- 有的学生只在一张表里出现,另一张表没有
- 两张表字段不完全相同
这说明:
数据集成不是简单拼接,而是带有判断、规则和清洗的合并过程。
二、什么是数据集成?
数据集成可以简单理解为:
把来自不同来源的数据,合并成一份更完整、更统一的数据集。
常见场景包括:
- 多个业务系统的数据整合
- 多张 Excel 表的汇总
- 不同部门的数据打通
- 不同时间采集的数据合并
数据集成的目标不是"把数据凑在一起",而是:
- 让字段名称更统一
- 让对象标识更一致
- 让重复数据更少
- 让冲突数据更可解释
- 为后续分析做准备
三、数据集成时最常见的 4 类问题
在实际操作中,数据集成通常会遇到下面这些问题。
1)实体识别:它们是不是同一个对象?
这是第一步,也是最关键的一步。
例如:
student_idstu_no学号
这三个字段名不同,但可能表示的是同一个东西:学生编号。
再比如:
customer_idcust_no
也可能表示同一个客户编号。
所以数据集成前,要先判断:
不同表里的字段,哪些其实是同一个含义?
这一步就叫实体识别或字段匹配。
2)重复记录:为什么同一个人出现了两次?
在多来源数据里,重复记录非常常见。
例如:
- 同一个学生被重复录入
- 导出数据时多导了一次
- 两个系统都保留了同一条信息
这类问题如果不处理,会导致:
- 统计结果被重复计算
- 平均值、计数结果不准确
- 后续分析偏差变大
3)数据冗余:这些字段是不是重复表达了同一件事?
冗余不一定表现为"完全相同",也可能是:
- 一个字段可以由另一个字段推导出来
- 两个字段表达的其实是同一类信息
- 因字段命名不同导致看起来像两列,实际含义很接近
例如:
出生年份和年龄总成绩和平时成绩 + 期末成绩班级名称和班级编号 + 班级类别
这类冗余字段如果太多,会让数据表显得混乱,也会影响分析效率。
4)数据冲突:同一个对象的值不一致怎么办?
这是数据集成中特别常见的问题。
例如:
- 教务系统里张三的手机号是 A
- 学工系统里张三的手机号是 B
再比如:
- 一个系统里李四的专业是"软件技术"
- 另一个系统里却写成"软件工程技术"
这类问题就叫数据冲突。
这时候不能简单"谁先来就用谁",而要结合:
- 数据来源是否权威
- 哪个系统更新时间更近
- 哪个字段业务上更可靠
四、案例:合并两张学生数据表
下面我们用 Pandas 做一遍简单的数据集成。
1)先统一字段名
两张表要想合并,首先得让关键字段"对得上"。
比如这里:
student_idstu_no
其实都表示学号。
我们先把 stu_no 改成统一的字段名:
python
df_attendance = df_attendance.rename(columns={'stu_no': 'student_id'})
print(df_attendance)
这一步非常重要,因为:
字段名不统一,后面就没法正确合并。
2)检测重复记录
现在来看 df_attendance,李四出现了两次。
我们先检查一下重复数据。
python
print(df_attendance.duplicated())
如果想看有多少条重复记录,可以写:
python
print(df_attendance.duplicated().sum())
如果想查看重复的具体内容:
python
print(df_attendance[df_attendance.duplicated()])
如何理解 duplicated()?
True:表示这行和前面某行重复False:表示不是重复行
3)删除重复记录
如果确认是完全重复的数据,可以直接删除:
python
df_attendance = df_attendance.drop_duplicates()
print(df_attendance)
如果想按某个关键字段去重,比如按 student_id 保留一条,也可以写:
python
df_attendance = df_attendance.drop_duplicates(subset=['student_id'])
print(df_attendance)
这在实际工作中非常常用,因为:
有时不是整行完全相同,但同一个对象只需要保留一条。
4)合并两张表
字段统一、重复值处理后,就可以开始合并。
python
df_merge = pd.merge(df_score, df_attendance, on='student_id', how='outer')
print(df_merge)
参数说明
on='student_id':按学号合并how='outer':保留两张表中的全部记录
常见合并方式有:
inner:取交集left:以左表为主right:以右表为主outer:取并集
对于初学者来说,outer 最容易看出哪些记录来自不同来源。
五、完整代码:字段统一 + 去重 + 合并
下面给出一份可以直接运行的完整代码。
python
import pandas as pd
# 1. 教务系统数据
df_score = pd.DataFrame({
'student_id': ['2023001', '2023002', '2023003', '2023004'],
'姓名': ['张三', '李四', '王五', '赵六'],
'数学成绩': [88, 76, 90, 82]
})
# 2. 学工系统数据
df_attendance = pd.DataFrame({
'stu_no': ['2023001', '2023002', '2023002', '2023005'],
'姓名': ['张三', '李四', '李四', '钱七'],
'考勤次数': [20, 18, 18, 19]
})
print("=== 原始教务数据 ===")
print(df_score)
print("\n=== 原始学工数据 ===")
print(df_attendance)
# 3. 统一字段名
df_attendance = df_attendance.rename(columns={'stu_no': 'student_id'})
print("\n=== 字段统一后的学工数据 ===")
print(df_attendance)
# 4. 检测重复记录
print("\n=== 是否重复 ===")
print(df_attendance.duplicated())
print("\n=== 重复记录数量 ===")
print(df_attendance.duplicated().sum())
print("\n=== 重复记录内容 ===")
print(df_attendance[df_attendance.duplicated()])
# 5. 删除重复记录
df_attendance = df_attendance.drop_duplicates(subset=['student_id'])
print("\n=== 去重后的学工数据 ===")
print(df_attendance)
# 6. 合并数据
df_merge = pd.merge(df_score, df_attendance, on='student_id', how='outer')
print("\n=== 合并后的数据 ===")
print(df_merge)
六、合并之后,结果应该怎么看?
合并后的表一般会出现几种情况:
1)两边都有数据
说明这个对象在两个系统里都存在,匹配成功。
2)左边有、右边没有
说明这个对象只出现在左表。
3)右边有、左边没有
说明这个对象只出现在右表。
这类"匹配不上"的情况非常常见,不一定是错误,可能只是:
- 不同系统覆盖范围不同
- 某个对象还没录入另一个系统
- 数据更新时间不同
所以集成后,除了看"有没有合上",还要看:
为什么没有完全合上。
七、遇到数据冲突时怎么办?
这是数据集成里最难、也最接近真实业务的问题。
假设合并后出现了这种情况:
- 同一个学生,姓名一样,学号一样
- 但联系方式、专业、班级等字段值不一致
处理思路通常有这几种:
1)以权威系统为准
比如学籍数据一般以教务系统为准。
2)以最新时间为准
如果有更新时间字段,可以优先使用最新记录。
3)人工核对
如果业务上非常重要,最好人工确认。
4)保留冲突标记
先不强行覆盖,而是保留两个值,并标记为"冲突待核查"。
这一步特别适合课堂上引导学生思考:
数据处理不是只有"技术动作",还有业务判断。
八、最容易踩的坑
坑1:字段名不同,就以为不能合并
其实很多时候只是名字不同,含义相同。
关键是先做字段匹配。
坑2:只会"拼表",不会"核对"
合并数据不是目的,合并后是否合理才重要。
坑3:重复数据只看整行是否相同
实际工作中,很多重复并不是"整行完全重复",而是同一个对象重复出现。
所以经常需要按关键字段去重。
坑4:遇到冲突值,随便保留一个
这很危险。
冲突值的处理要有依据,比如:
- 来源是否可靠
- 时间是否更新
- 业务上哪个字段更权威
九、这部分知识有什么实际用处?
数据集成与重复值处理,在真实工作里几乎天天会遇到。
例如:
- 学生学情分析
- 客户画像合并
- 订单数据整合
- 用户行为数据打通
- 多张 Excel 报表汇总
如果不会做数据集成,后面很多分析就根本没法开展。
也就是说:
分析能力的前提之一,是先把数据真正"整理到一起"。
十、给初学者的记忆口诀
这部分你可以先记住下面这 4 句话:
- 数据集成不是简单拼表,而是带规则的合并。
- 先统一字段,再检测重复,再做合并。
- 重复值处理要看"整行重复"还是"对象重复"。
- 冲突数据不能随便选,要结合来源和业务判断。
十一、课后练习(适合课堂 / 自学)
练习 1:基础题
已知两张学生数据表:
python
df1 = pd.DataFrame({
'student_id': ['001', '002', '003'],
'姓名': ['A', 'B', 'C'],
'成绩': [80, 85, 90]
})
df2 = pd.DataFrame({
'stu_no': ['001', '002', '004'],
'姓名': ['A', 'B', 'D'],
'考勤': [20, 18, 19]
})
请完成:
- 统一两个表的关键字段名
- 合并两张表
- 观察哪些学生只出现在一张表里
- 用一句话说明你的发现
练习 2:提高题
已知数据:
python
df = pd.DataFrame({
'student_id': ['001', '002', '002', '003'],
'姓名': ['A', 'B', 'B', 'C'],
'成绩': [80, 85, 85, 90]
})
请完成:
- 检测是否有重复记录
- 统计重复记录数量
- 删除重复记录
- 思考:如果两条
002的成绩不一样,该怎么处理?
练习 3:迁移题
请把"学生数据"替换成你熟悉的业务场景,例如:
- 某店铺订单表和用户表
- 某宿舍信息表和考勤表
- 某门课程成绩表和问卷表
要求:
- 找出两个表中对应的关键字段
- 完成数据合并
- 检测重复值
- 说明是否存在冲突字段
- 给出你的处理建议
十二、总结
这篇文章主要解决了一个非常实际的问题:
来自不同来源的数据,到底该怎么合到一起?
我们通过一个简单的学生数据案例,学习了:
- 什么是数据集成
- 为什么不能简单拼表
- 数据集成中的几个典型问题
- 如何统一字段名
- 如何检测和删除重复记录
- 如何做基础的数据合并
其中最重要的思路是:
- 先匹配
- 再清洗
- 后合并
- 最后核对
对于数据分析初学者来说,这是一项非常基础但非常实用的能力。
十三、写在最后
如果这篇文章对你有帮助,欢迎点赞、收藏、评论支持一下。
如果你也在学习 Python 数据分析,建议把 rename()、merge()、duplicated()、drop_duplicates() 这几个方法先练熟,它们在数据预处理中真的非常常用。
你在做数据合并时,最容易遇到的是"字段对不上"还是"数据重复"呢?
欢迎在评论区交流。