文章目录
- [第四章 数据集成](#第四章 数据集成)
- 第1课时:数据集成概述
- 一、课程基本信息
- 二、教学目标
- 三、教学重点
- 四、教学内容
- [4.1 数据集成概述](#4.1 数据集成概述)
-
- [4.1.1 初识数据集成](#4.1.1 初识数据集成)
-
- [1. 数据集成定义](#1. 数据集成定义)
- [2. 为什么需要数据集成?](#2. 为什么需要数据集成?)
- [3. 信息孤岛](#3. 信息孤岛)
- 五、数据集成系统模型
- 六、数据集成架构
- [4.1.2 ETL架构](#4.1.2 ETL架构)
- [4.1.3 ELT架构](#4.1.3 ELT架构)
- 七、数据集成中的关键问题
- 八、冗余属性识别
-
- [1. 什么是冗余属性?](#1. 什么是冗余属性?)
- [2. 冗余产生原因](#2. 冗余产生原因)
- 九、实体识别
-
- [1. 实体概念](#1. 实体概念)
- [2. 实体识别目的](#2. 实体识别目的)
- 十、实体识别三类问题
-
- [1. 同名异义](#1. 同名异义)
- [2. 异名同义](#2. 异名同义)
- [3. 单位不统一](#3. 单位不统一)
- 十一、课堂案例
- 十二、课堂练习
- 十三、本课总结
-
- [1. 数据集成](#1. 数据集成)
- [2. 数据集成架构](#2. 数据集成架构)
- [3. 数据集成问题](#3. 数据集成问题)
- 十四、课后作业
- 《Python数据预处理》
- [第四章 数据集成](#第四章 数据集成)
- 第2课时教学设计
- 一、课程基本信息
- 二、本课教学目标
- 三、教学重点与难点
- 四、教学导入(10分钟)
- 五、知识讲授
- [5.1 主键合并数据的基本思想](#5.1 主键合并数据的基本思想)
-
- [5.1.1 什么是主键合并?](#5.1.1 什么是主键合并?)
- [5.1.2 为什么不能直接concat?](#5.1.2 为什么不能直接concat?)
- [5.2 Pandas的merge()函数](#5.2 Pandas的merge()函数)
- [5.3 merge()主要参数](#5.3 merge()主要参数)
-
- [1. left和right](#1. left和right)
- [2. on参数](#2. on参数)
- [3. left_on和right_on](#3. left_on和right_on)
- [4. how参数](#4. how参数)
- [5. suffixes参数](#5. suffixes参数)
- [5.4 merge()基本案例](#5.4 merge()基本案例)
- [5.5 how参数四种连接方式](#5.5 how参数四种连接方式)
- [5.5.1 左连接 left join](#5.5.1 左连接 left join)
- [5.5.2 右连接 right join](#5.5.2 右连接 right join)
- [5.5.3 外连接 outer join](#5.5.3 外连接 outer join)
- [5.5.4 内连接 inner join](#5.5.4 内连接 inner join)
- [5.6 四种连接方式对比](#5.6 四种连接方式对比)
- [5.7 join()方法](#5.7 join()方法)
-
- [5.7.1 join()基本概念](#5.7.1 join()基本概念)
- [5.7.2 索引一致时](#5.7.2 索引一致时)
- [5.7.3 索引不一致时](#5.7.3 索引不一致时)
- [5.7.4 相同列名问题](#5.7.4 相同列名问题)
- 六、merge()与join()对比
- 七、课堂案例分析
- 八、课堂练习
- 九、实验2:学生信息主键合并实验
-
- [1. 实验名称](#1. 实验名称)
- [2. 实验目的](#2. 实验目的)
- [3. 实验环境](#3. 实验环境)
- [4. 实验数据](#4. 实验数据)
- [5. 实验内容](#5. 实验内容)
- 十、实验结果分析
-
- [1. inner连接结果](#1. inner连接结果)
- [2. left连接结果](#2. left连接结果)
- [3. right连接结果](#3. right连接结果)
- [4. outer连接结果](#4. outer连接结果)
- 十一、课堂思考题
- 十二、课堂总结
-
- [1. 主键合并](#1. 主键合并)
- [2. merge()](#2. merge())
- [3. how参数](#3. how参数)
- [4. join()](#4. join())
- 十三、课后作业
- 十四、实验报告要求
- 《Python数据预处理》
- [第四章 数据集成](#第四章 数据集成)
- 第3课时教学设计
- 一、课程基本信息
- 二、本课教学目标
- 三、教学重点与难点
- 四、PPT页码对应
- 五、教学导入(10分钟)
- 六、知识讲授
- [6.1 堆叠合并数据](#6.1 堆叠合并数据)
- [6.2 Pandas的concat()函数](#6.2 Pandas的concat()函数)
- [6.3 索引重复问题](#6.3 索引重复问题)
- [6.4 keys参数](#6.4 keys参数)
- [6.5 axis=1横向合并](#6.5 axis=1横向合并)
- [6.6 join参数](#6.6 join参数)
- [6.7 NumPy的concatenate()函数](#6.7 NumPy的concatenate()函数)
- [6.8 append()方法](#6.8 append()方法)
- [七、4.4 重叠合并数据](#七、4.4 重叠合并数据)
-
- [7.1 什么是重叠合并?](#7.1 什么是重叠合并?)
- [7.2 combine()方法](#7.2 combine()方法)
- [7.3 combine()案例1------按列选择](#7.3 combine()案例1——按列选择)
- [7.4 combine()案例2------对应位置取最小值](#7.4 combine()案例2——对应位置取最小值)
- [7.5 fill_value参数](#7.5 fill_value参数)
- [7.6 combine_first()方法](#7.6 combine_first()方法)
- 八、merge、concat、combine_first对比
- 九、课堂案例分析
- 十、实验3:多门店销售数据集成实验
-
- [1. 实验名称](#1. 实验名称)
- [2. 实验目的](#2. 实验目的)
- [3. 实验环境](#3. 实验环境)
- 十一、学生代码文件
- 十二、实验数据文件
- 十三、实验步骤
- 十四、实验结果分析
-
-
- [1. 三个门店原始数据分别有多少行?](#1. 三个门店原始数据分别有多少行?)
- [2. concat以后共有多少行?](#2. concat以后共有多少行?)
- [3. ignore_index=True的作用是什么?](#3. ignore_index=True的作用是什么?)
- [4. axis=0和axis=1有什么区别?](#4. axis=0和axis=1有什么区别?)
- [5. customer_main中哪些字段存在缺失?](#5. customer_main中哪些字段存在缺失?)
- [6. combine_first以后哪些缺失数据得到补充?](#6. combine_first以后哪些缺失数据得到补充?)
-
- 十五、教师讲稿
- 十六、课堂总结
-
- [1. 堆叠](#1. 堆叠)
- [2. 数组拼接](#2. 数组拼接)
- [3. 规则组合](#3. 规则组合)
- [4. 数据补丁](#4. 数据补丁)
- 十七、课后作业
- 十八、实验报告模板
- 《Python数据预处理》
- [第四章 数据集成](#第四章 数据集成)
- 第4课时教学设计
- 一、课程基本信息
- 二、本课教学目标
- 三、教学重点与难点
- 四、PPT页码对应
- 五、建议教学时间分配
- 六、教学导入(5分钟)
- 七、知识讲授
- [7.1 认识Scikit-learn](#7.1 认识Scikit-learn)
- [7.2 什么是集成学习?](#7.2 什么是集成学习?)
- [7.3 Bagging](#7.3 Bagging)
- [7.4 Boosting](#7.4 Boosting)
- [7.5 随机森林](#7.5 随机森林)
- [7.6 AdaBoost与GBDT](#7.6 AdaBoost与GBDT)
- 八、数据集拆分
- [8.1 为什么拆分数据?](#8.1 为什么拆分数据?)
- [8.2 训练集、验证集、测试集](#8.2 训练集、验证集、测试集)
-
- [训练集 Train](#训练集 Train)
- [验证集 Validation](#验证集 Validation)
- [测试集 Test](#测试集 Test)
- [8.3 数据拆分比例](#8.3 数据拆分比例)
- [8.4 留出法](#8.4 留出法)
- [8.5 K折交叉验证](#8.5 K折交叉验证)
- [8.6 Bootstrap自助法](#8.6 Bootstrap自助法)
- 九、train_test_split()代码演示
- 十、课堂案例导入------探索虚拟姓名数据
- 十一、任务分析
- 十二、实验4:探索虚拟姓名数据
-
- [1. 实验名称](#1. 实验名称)
- [2. 实验目的](#2. 实验目的)
- [3. 实验环境](#3. 实验环境)
- 十三、实验数据
- 十四、学生代码文件
- 十五、实验步骤
- 十六、实验结果分析
- 十七、教师讲稿
- 十八、课堂总结
- 十九、课堂思考题
- 二十、课后作业
- 二十一、实验报告模板
-
- 《Python数据预处理》实验报告
- 一、实验目的
- 二、实验环境
- 三、实验数据说明
- 四、实验过程
-
- [1. 创建DataFrame](#1. 创建DataFrame)
- [2. data1与data2按行合并](#2. data1与data2按行合并)
- [3. data1与data2按列合并](#3. data1与data2按列合并)
- [4. 按subject_id进行主键合并](#4. 按subject_id进行主键合并)
- [5. inner连接](#5. inner连接)
- [6. outer连接](#6. outer连接)
- [7. 保存数据](#7. 保存数据)
- 五、实验结果对比
- 六、结果分析
- 七、实验总结
- 八、拓展思考
第四章 数据集成
第1课时:数据集成概述
一、课程基本信息
章节名称
第四章 数据集成
本课主题
4.1 数据集成概述
主要内容:
- 数据集成基本概念
- 数据集成架构
- 冗余属性识别
- 实体识别
- 数据不一致问题
二、教学目标
(一)知识目标
通过本节学习,使学生能够:
-
理解数据集成的基本概念。
-
掌握数据集成在数据预处理流程中的作用。
-
了解ETL和ELT两种数据集成架构。
-
掌握数据集成过程中常见问题:
- 冗余属性
- 实体识别
- 数据不一致
(二)能力目标
学生能够:
-
根据实际数据分析场景判断是否需要数据集成。
-
分析多个数据源之间存在的问题。
-
理解企业数据仓库中的数据整合过程。
(三)素质目标
培养学生:
-
数据工程意识。
-
数据质量意识。
-
多源数据统一管理意识。
三、教学重点
重点1:理解数据集成的意义
在实际数据分析过程中,数据通常来自不同来源:
例如:
- 企业业务数据库
- 用户系统
- 销售系统
- 财务系统
- 网络采集数据
不同来源的数据通常存在:
- 格式不同
- 存储方式不同
- 字段定义不同
因此需要数据集成。
四、教学内容
4.1 数据集成概述
4.1.1 初识数据集成
1. 数据集成定义
教师讲解:
数据集成是指:
将不同来源、不同格式、不同特点的数据,在逻辑或物理上进行集中,使多个数据源形成统一的数据存储。
PPT中指出:
数据集成的核心任务是:
将互相关联的异构数据源集成到一起,使用户能够透明访问这些数据资源。
2. 为什么需要数据集成?
教师提问:
一个企业如果有多个系统,每个系统保存自己的数据,会产生什么问题?
学生思考:
例如:
某电商企业:
用户系统:
| 用户编号 | 姓名 |
|---|---|
| 1001 | 张三 |
订单系统:
| 客户ID | 购买金额 |
|---|---|
| 1001 | 500 |
商品系统:
| 用户编号 | 浏览商品 |
|---|---|
| 1001 | 手机 |
三个系统:
都有用户信息。
但是:
- 字段名称不同
- 数据格式不同
- 数据更新不同步
导致:
信息孤岛。
3. 信息孤岛
定义
信息孤岛:
指不同软件系统之间,尤其不同部门之间的数据不能共享。
造成:
- 数据重复
- 数据垃圾
- 数据不一致
严重影响企业信息化建设。
五、数据集成系统模型
1. 基本结构
数据集成系统包括:
数据源层
提供原始数据。
例如:
- 数据库
- Excel
- 网络接口
↓
数据集成层
完成:
- 数据读取
- 数据转换
- 数据合并
↓
用户访问层
提供:
- 查询
- 分析
- 数据应用
2. 工作流程
text
数据源1
数据源2
数据源3
↓
数据集成系统
↓
用户
教师说明:
用户不需要知道:
数据来自哪里。
只需要访问统一接口。
这种方式称为:
透明访问。
六、数据集成架构
数据集成主要包括:
- ETL
- ELT
4.1.2 ETL架构
一、ETL含义
ETL:
Extract
(提取)
Transform
(转换)
Load
(加载)
二、ETL流程
text
原始数据
↓
Extract
数据抽取
↓
Transform
数据转换
↓
Load
加载到目标数据库
三、案例
银行数据分析:
数据来源:
贷款系统
↓
提取:
客户信息
↓
转换:
统一日期格式
↓
加载:
数据仓库
用于:
风险分析。
4.1.3 ELT架构
一、ELT流程
Extract
↓
Load
↓
Transform
二、与ETL区别
| 比较 | ETL | ELT |
|---|---|---|
| 转换位置 | 加载前 | 加载后 |
| 特点 | 提前处理 | 利用数据库计算 |
| 适合 | 传统数据仓库 | 大数据环境 |
三、ELT优势
-
数据加载更快。
-
保留原始数据。
-
支持灵活分析。
PPT指出:
ELT采用"重抽取和加载、轻转换"的方式,提高数据处理灵活性。
七、数据集成中的关键问题
数据集成过程中主要解决:
-
冗余属性识别
-
实体识别
-
数据不一致
八、冗余属性识别
1. 什么是冗余属性?
数据集中:
存在多个字段表达相同信息。
例如:
数据源A:
| 字段 |
|---|
| 电话号码 |
数据源B:
| 字段 |
|---|
| 联系电话 |
两个字段实际含义相同。
2. 冗余产生原因
(1)同一属性多次出现
例如:
两个系统都保存:
最高温度。
合并后:
出现两个最高温度字段。
(2)命名不同造成重复
例如:
python
sale_date
sales_dt
实际表示:
销售日期。
九、实体识别
1. 实体概念
实体:
客观存在并且可以区别的事物。
例如:
- 人
- 商品
- 订单
- 企业
2. 实体识别目的
不同数据源:
可能描述同一个对象。
需要判断:
是否是同一个实体。
十、实体识别三类问题
1. 同名异义
名称一样:
含义不同。
案例:
字段:
ID
系统A:
商品编号
系统B:
订单编号
2. 异名同义
名字不同:
含义相同。
例如:
text
customer_name
client_name
都表示:
客户姓名。
3. 单位不统一
案例:
身高:
系统A:
1.75米
系统B:
175厘米
需要统一。
十一、课堂案例
案例:学生信息系统整合
已有:
学生基本信息表:
| 学号 | 姓名 | 年龄 |
|---|---|---|
| 001 | 张三 | 20 |
成绩表:
| 学生编号 | 数学 |
|---|---|
| 001 | 90 |
问题:
-
两个编号是否代表同一个实体?
-
是否可以直接合并?
-
是否存在字段重复?
十二、课堂练习
练习1
判断以下情况属于哪类问题:
情况1:
数据库A:
phone
数据库B:
telephone
答案:
异名同义。
情况2:
数据库A:
ID=商品编号
数据库B:
ID=订单编号
答案:
同名异义。
情况3:
数据库A:
年龄
数据库B:
age
答案:
字段名称不同,需要实体识别。
十三、本课总结
本节主要学习:
1. 数据集成
作用:
解决信息孤岛。
2. 数据集成架构
包括:
- ETL
- ELT
3. 数据集成问题
包括:
- 冗余属性
- 实体识别
- 数据不一致
十四、课后作业
理论题
-
什么是数据集成?
-
ETL和ELT有什么区别?
-
什么是信息孤岛?
实践题
某企业有:
用户表.csv
订单表.csv
商品表.csv
分析:
-
哪些字段可能存在冗余?
-
哪些字段需要实体识别?
-
如何设计数据集成方案?
《Python数据预处理》
第四章 数据集成
第2课时教学设计
主题:主键合并数据------merge()与join()方法
一、课程基本信息
课程名称:《Python数据预处理》
所属章节:第四章 数据集成
课时安排:第2课时(2学时)
教学主题:主键合并数据
主要内容:
- 主键合并数据的基本思想
- Pandas的
merge()函数 merge()函数常用参数- Pandas的
join()方法 how参数四种连接方式- CSV文件主键合并综合案例
教学方式:
讲授法 + 案例教学法 + 代码演示 + 课堂练习 + 实验实践
教学环境:
- Python 3.x
- Jupyter Notebook
- Pandas
二、本课教学目标
(一)知识目标
-
理解主键合并数据的基本概念。
-
理解连接键在数据合并中的作用。
-
掌握Pandas中
merge()函数的基本使用方法。 -
掌握
merge()函数中的常用参数:
leftrightonleft_onright_onleft_indexright_indexhowsuffixes
-
掌握Pandas中
join()方法的基本使用方法。 -
理解并掌握四种主键连接方式:
- left
- right
- outer
- inner
- 理解不同连接方式产生NaN值的原因。
(二)能力目标
-
能够根据实际数据表结构选择合理的连接键。
-
能够使用
merge()函数对两个DataFrame进行主键合并。 -
能够根据业务要求选择内连接、左连接、右连接或外连接。
-
能够处理两个数据表字段名称不一致的情况。
-
能够使用
join()方法根据索引完成数据合并。 -
能够读取两个CSV文件并完成真实数据集成任务。
(三)素养目标
-
培养学生规范的数据整合意识。
-
培养学生在合并数据前检查主键唯一性和字段含义的习惯。
-
建立"数据合并不是简单拼接,而是依据业务关系建立数据关联"的意识。
-
培养学生从实际业务需求出发选择数据合并方式的能力。
三、教学重点与难点
(一)教学重点
重点1:连接键的理解
主键合并的核心是找到两个数据表之间能够建立对应关系的字段。
例如:
学生基本信息表:
| 学号 | 姓名 | 年龄 |
|---|---|---|
| S01 | 张千 | 16 |
| S02 | 李峰 | 15 |
学生成绩表:
| 学号 | 语文 | 数学 |
|---|---|---|
| S01 | 86 | 86 |
| S02 | 85 | 75 |
两个表中共同的"学号"字段可以作为连接键。
PPT指出,主键合并的关键在于指定一个键,对DataFrame数据表进行连接。
重点2:merge()函数
掌握基本形式:
python
pd.merge(
left,
right,
on="学号"
)
理解:
left:左表right:右表on:连接字段
重点3:how参数
掌握:
python
how="left"
how="right"
how="outer"
how="inner"
并理解四种方式的区别。
重点4:join()方法
理解join()默认依据索引进行连接。
掌握:
python
df1.join(df2)
(二)教学难点
难点1:选择正确的连接键
不能因为两个字段名称一样,就直接认为它们可以作为连接键。
例如:
表A:
text
ID = 商品编号
表B:
text
ID = 订单编号
虽然都叫"ID",但表示不同实体,不能直接合并。
难点2:理解不同how参数的结果
例如:
左表存在S03,右表不存在S03。
如果使用:
python
how="left"
则S03会保留,但右表相关字段会出现NaN。
如果使用:
python
how="inner"
则S03会直接消失。
学生需要理解这种差异不是程序错误,而是连接规则不同。
难点3:处理字段重名
如果两个表都含有"姓名"字段,合并后可能出现:
text
姓名_x
姓名_y
需要理解后缀产生的原因。
四、教学导入(10分钟)
案例:学生信息为什么分散在两个系统?
某学校存在两个信息系统。
教务系统
保存:
| 学号 | 姓名 | 年龄 |
|---|---|---|
| S01 | 张千 | 16 |
| S02 | 李峰 | 15 |
| S03 | 王诗 | 14 |
| S04 | 吴芸 | 17 |
成绩系统
保存:
| 学号 | 姓名 | 语文 | 数学 | 英语 |
|---|---|---|---|---|
| S01 | 张千 | 86 | 86 | 96 |
| S02 | 李峰 | 85 | 75 | 85 |
| S05 | 白松 | 84 | 74 | 94 |
教师提出问题:
- 如果需要分析学生年龄和成绩之间的关系,应该怎么办?
- 两个表能否直接上下拼接?
- 两个表中哪个字段最适合作为连接依据?
- S03、S04和S05应该如何处理?
引导学生回答:
两个表应该按照"学号"建立对应关系。
从而引出本课主题:
主键合并数据。
五、知识讲授
5.1 主键合并数据的基本思想
5.1.1 什么是主键合并?
主键合并就是:
根据两个数据表中的共同字段建立数据之间的对应关系,再将两个数据表的信息组合到一起。
例如:
学生基本信息:
text
S01 张千 16
学生成绩:
text
S01 86 86 96
按照学号S01合并:
text
S01 张千 16 86 86 96
5.1.2 为什么不能直接concat?
教师可进行对比说明:
concat()主要强调数据在行或列方向上的堆叠。
而:
merge()强调的是:
根据某个具有业务意义的字段建立数据对应关系。
例如:
一个学生只能把自己的成绩连接到自己的基本信息中,因此必须根据学号进行匹配。
5.2 Pandas的merge()函数
PPT中指出,merge()可以将两个DataFrame按照指定规则连接,最后形成一个新的DataFrame。
基本语法:
python
pd.merge(
left,
right,
how="inner",
on=None,
left_on=None,
right_on=None
)
5.3 merge()主要参数
1. left和right
表示需要合并的两个DataFrame对象。
例如:
python
pd.merge(
df_left,
df_right
)
2. on参数
指定两个表共同使用的连接键。
例如:
python
pd.merge(
df_left,
df_right,
on="学号"
)
要求:
"学号"必须同时存在于两个DataFrame中。
PPT中说明,如果没有指定其他连接参数,merge()会根据两个DataFrame列名的交集确定连接键。
教师强调:
实际项目中建议主动指定on,避免程序自动选择错误字段。
3. left_on和right_on
当两个表中字段名称不同,但是含义相同时使用。
例如:
左表:
text
学号
右表:
text
student_id
代码:
python
pd.merge(
df_left,
df_right,
left_on="学号",
right_on="student_id"
)
4. how参数
决定最终保留哪些连接键。
取值:
text
left
right
outer
inner
5. suffixes参数
当两个DataFrame中存在同名字段时:
例如:
两个表都有:
text
姓名
合并后默认变成:
text
姓名_x
姓名_y
可以指定:
python
pd.merge(
df_left,
df_right,
on="学号",
suffixes=("_基本信息", "_成绩表")
)
5.4 merge()基本案例
PPT中的例4-1使用学生信息和成绩数据演示按"学号"进行合并。
代码:
python
import pandas as pd
df_left = pd.DataFrame({
"学号": ["S01", "S02", "S03", "S04"],
"姓名": ["张千", "李峰", "王诗", "吴芸"],
"年龄": [16, 15, 14, 17]
})
df_right = pd.DataFrame({
"学号": ["S01", "S02", "S05"],
"姓名": ["张千", "李峰", "白松"],
"语文": [86, 85, 84],
"数学": [86, 75, 74],
"英语": [96, 85, 94]
})
result = pd.merge(
df_left,
df_right,
on="学号"
)
print(result)
运行结果分析
默认情况下:
python
how="inner"
所以只有两个表都存在的:
text
S01
S02
被保留。
最终结果:
| 学号 | 姓名_x | 年龄 | 姓名_y | 语文 | 数学 | 英语 |
|---|---|---|---|---|---|---|
| S01 | 张千 | 16 | 张千 | 86 | 86 | 96 |
| S02 | 李峰 | 15 | 李峰 | 85 | 75 | 85 |
PPT中的示例也显示默认合并后只保留两个数据表共有的S01和S02。
5.5 how参数四种连接方式
这是本课最重要的知识点。
教师可以先画集合图:
text
左表:S01 S02 S03 S04
右表:S01 S02 S05
共同部分:
text
S01 S02
5.5.1 左连接 left join
代码:
python
pd.merge(
df_left,
df_right,
on="学号",
how="left"
)
含义:
以左表为主体。
左表所有数据都保留。
结果中的学号:
text
S01
S02
S03
S04
对于S03、S04:
右表中找不到对应成绩,因此:
text
语文 = NaN
数学 = NaN
英语 = NaN
PPT左连接示例明确显示S03和S04被保留,而右表对应字段为NaN。
教师讲解
左连接非常适合这样的业务需求:
"我要保留所有学生,即使部分学生还没有成绩。"
例如:
学校有1000名学生。
成绩系统只有950人的成绩。
但是学校要求:
所有学生都必须出现在报表中。
此时:
使用left连接。
5.5.2 右连接 right join
代码:
python
pd.merge(
df_left,
df_right,
on="学号",
how="right"
)
含义:
以右表为主体。
结果保留:
text
S01
S02
S05
S05在左表中不存在:
因此:
年龄等字段为NaN。
PPT示例中右连接以右侧学号作为连接结果,S05得到保留。
5.5.3 外连接 outer join
代码:
python
pd.merge(
df_left,
df_right,
on="学号",
how="outer"
)
含义:
保留两个表中的所有键。
结果包括:
text
S01
S02
S03
S04
S05
也就是:
两个集合的并集。
PPT中outer示例即将两个学号集合求并集。
适用场景
例如:
希望检查两个系统中有哪些用户不一致。
可以使用outer。
这样能够同时看到:
- 左表独有数据
- 右表独有数据
- 两个表共有数据
5.5.4 内连接 inner join
代码:
python
pd.merge(
df_left,
df_right,
on="学号",
how="inner"
)
含义:
只保留两个表共同存在的数据。
结果:
text
S01
S02
也就是:
两个集合的交集。
5.6 四种连接方式对比
| 连接方式 | 结果范围 | 典型用途 |
|---|---|---|
| inner | 两表交集 | 只分析匹配成功的数据 |
| left | 保留左表全部 | 左表是核心业务对象 |
| right | 保留右表全部 | 右表是核心业务对象 |
| outer | 两表并集 | 检查不同数据源之间差异 |
教师要求学生记忆:
text
inner = 交集
outer = 并集
left = 左边全部保留
right = 右边全部保留
5.7 join()方法
5.7.1 join()基本概念
PPT指出:
join()也能够完成部分主键合并功能,其默认连接依据是DataFrame的行索引。
基本语法:
python
df1.join(df2)
5.7.2 索引一致时
代码:
python
import pandas as pd
x = pd.DataFrame({
"A": ["x1", "x2", "x3"],
"B": ["y1", "y2", "y3"]
}, index=[0, 1, 2])
y = pd.DataFrame({
"C": ["z1", "z2", "z3"],
"D": ["m1", "m2", "m3"]
}, index=[0, 1, 2])
result = x.join(y)
print(result)
结果:
| index | A | B | C | D |
|---|---|---|---|---|
| 0 | x1 | y1 | z1 | m1 |
| 1 | x2 | y2 | z2 | m2 |
| 2 | x3 | y3 | z3 | m3 |
该例对应PPT例4-2。
5.7.3 索引不一致时
左表:
text
0 1 2
右表:
text
1 2 3
使用:
python
x.join(y)
由于默认采用左连接:
左表索引0、1、2全部保留。
索引0在右表中不存在:
因此:
text
C = NaN
D = NaN
PPT例4-3即展示了这种结果。
5.7.4 相同列名问题
如果两个DataFrame存在相同字段:
例如:
text
B
直接使用:
python
x.join(y)
可能报错。
需要:
python
x.join(
y,
lsuffix="_left",
rsuffix="_right"
)
结果:
text
B_left
B_right
PPT强调,join()不会像merge()一样自动为重复列名添加后缀,需要通过lsuffix和rsuffix显式指定。
六、merge()与join()对比
| 项目 | merge() | join() |
|---|---|---|
| 默认连接依据 | 公共字段 | 行索引 |
| 默认连接方式 | inner | left |
| 字段名不同 | 支持left_on/right_on | 主要基于索引 |
| 重复列名处理 | 自动添加后缀 | 需要指定后缀 |
| 使用场景 | 主键字段合并 | 索引合并 |
教师提示:
实际DataFrame业务表连接时:
merge()更加常用。
如果数据已经设置好索引:
join()会比较方便。
七、课堂案例分析
案例:学生基本信息与成绩信息集成
文件1:student_info.csv
csv
学号,姓名,年龄
S01,张千,16
S02,李峰,15
S03,王诗,14
S04,吴芸,17
文件2:student_score.csv
csv
学号,语文,数学,英语
S01,86,86,96
S02,85,75,85
S05,84,74,94
问题1
如果只分析"既有基本信息又有考试成绩"的学生:
应该使用什么连接?
答案:
python
how="inner"
问题2
如果要求输出所有在籍学生,不管有没有考试成绩:
答案:
python
how="left"
问题3
如果需要检查两个系统所有学生数据:
答案:
python
how="outer"
八、课堂练习
练习1
请判断:
python
pd.merge(
a,
b,
on="用户ID",
how="inner"
)
表示什么?
要求学生回答:
只保留两个表中都存在的用户ID。
练习2
左表用户:
text
001
002
003
右表用户:
text
002
003
004
分别写出:
inner
text
002
003
left
text
001
002
003
right
text
002
003
004
outer
text
001
002
003
004
九、实验2:学生信息主键合并实验
1. 实验名称
学生基本信息与成绩数据集成实验
2. 实验目的
-
掌握CSV数据读取方法。
-
掌握
merge()函数。 -
掌握四种连接方式。
-
掌握
join()方法。 -
理解NaN产生的原因。
3. 实验环境
Python 3.x
Jupyter Notebook
Pandas
4. 实验数据
student_info.csv
csv
学号,姓名,年龄
S01,张千,16
S02,李峰,15
S03,王诗,14
S04,吴芸,17
student_score.csv
csv
学号,语文,数学,英语
S01,86,86,96
S02,85,75,85
S05,84,74,94
5. 实验内容
步骤1:读取文件
python
import pandas as pd
info = pd.read_csv(
"student_info.csv"
)
score = pd.read_csv(
"student_score.csv"
)
print(info)
print(score)
步骤2:内连接
python
inner_data = pd.merge(
info,
score,
on="学号",
how="inner"
)
print(inner_data)
记录结果中的学生数量。
步骤3:左连接
python
left_data = pd.merge(
info,
score,
on="学号",
how="left"
)
print(left_data)
观察:
哪些学生成绩为NaN?
步骤4:右连接
python
right_data = pd.merge(
info,
score,
on="学号",
how="right"
)
print(right_data)
观察:
哪名学生没有基本信息?
步骤5:外连接
python
outer_data = pd.merge(
info,
score,
on="学号",
how="outer"
)
print(outer_data)
统计最终共有多少名不同学生。
步骤6:保存结果
python
outer_data.to_csv(
"student_all.csv",
index=False,
encoding="utf-8-sig"
)
十、实验结果分析
学生需要填写:
1. inner连接结果
共有:
____ 条数据。
2. left连接结果
共有:
____ 条数据。
缺失成绩的学生为:
________。
3. right连接结果
共有:
____ 条数据。
缺少基本信息的学生为:
________。
4. outer连接结果
共有:
____ 条数据。
十一、课堂思考题
-
为什么主键字段最好具有唯一性?
-
如果一个学号在成绩表中出现两次,merge后会发生什么?
-
为什么outer连接特别适合用于检查两个系统之间的数据差异?
-
merge产生NaN是否意味着代码出现错误?
-
merge和concat的本质区别是什么?
十二、课堂总结
本课知识体系:
1. 主键合并
核心:
text
找到连接键
↓
2. merge()
python
pd.merge()
↓
3. how参数
text
inner:交集
left:左表全部
right:右表全部
outer:并集
↓
4. join()
主要按照:
text
DataFrame索引
进行连接。
十三、课后作业
(一)理论题
-
简述
merge()函数的作用。 -
on、left_on和right_on分别有什么作用? -
left连接和inner连接有什么区别?
-
merge和join有什么区别?
-
两个数据表合并后为什么可能产生NaN?
(二)实践题
提供两个文件:
customer.csv
包含:
text
客户编号
姓名
年龄
order.csv
包含:
text
客户编号
订单编号
订单金额
要求:
-
读取两个文件。
-
查看数据结构。
-
使用inner方式合并。
-
使用left方式合并。
-
使用outer方式合并。
-
比较三种结果。
-
保存最终数据为:
text
customer_order.csv
十四、实验报告要求
实验报告应包含:
一、实验名称
学生信息主键合并实验
二、实验目的
三、实验环境
四、实验数据说明
五、实验步骤
六、主要程序代码
七、运行结果
要求分别截图:
- inner连接
- left连接
- right连接
- outer连接
八、结果分析
重点分析:
四种连接方式的数据数量差异及NaN产生原因。
九、实验总结
总结:
什么时候选择inner、left、right和outer。
《Python数据预处理》
第四章 数据集成
第3课时教学设计
主题:堆叠合并数据与重叠合并数据
一、课程基本信息
课程名称:《Python数据预处理》
所属章节:第四章 数据集成
课时安排:第3课时(2学时)
教学主题:堆叠合并数据与重叠合并数据
主要教学内容:
- 堆叠合并数据的基本思想
- Pandas的
concat()函数 axis、join、ignore_index、keys等参数- NumPy的
concatenate()函数 append()方法- 重叠合并数据的基本思想
combine()方法combine_first()方法- 多来源数据堆叠与缺失信息补充综合实验
教学方式:
讲授法 + 对比教学法 + 案例教学法 + Python代码演示 + 综合实验
教学环境:
- Python 3.x
- Jupyter Notebook
- Pandas
- NumPy
二、本课教学目标
(一)知识目标
-
理解堆叠合并数据的基本含义。
-
掌握Pandas的
concat()函数。 -
理解
concat()中常用参数的作用:
axisjoinignore_indexkeys
-
能够区分按行合并和按列合并。
-
了解NumPy中的
concatenate()函数。 -
了解
append()方法的作用。 -
理解重叠合并数据的含义。
-
掌握
combine()函数的基本使用方法。 -
掌握
combine_first()方法填充缺失数据的基本思想。
(二)能力目标
-
能够判断两个数据表应该采用主键合并还是堆叠合并。
-
能够使用
concat()完成多个DataFrame的纵向和横向合并。 -
能够解决数据堆叠后索引重复的问题。
-
能够利用
concatenate()完成NumPy数组的拼接。 -
能够根据实际需求使用
combine()进行对应位置的数据比较和组合。 -
能够利用
combine_first()使用另一份数据补充当前数据中的缺失信息。 -
能够完成多月份、多部门或多来源数据的综合集成。
(三)素养目标
-
培养学生根据数据结构选择数据集成方法的意识。
-
培养学生在数据合并过程中关注索引、字段和缺失值变化的习惯。
-
建立"不同行业场景采用不同集成策略"的数据工程意识。
-
培养学生在数据处理后进行结果验证的严谨习惯。
三、教学重点与难点
(一)教学重点
重点1:concat()函数
本课最核心的知识点是:
python
pd.concat()
PPT指出,concat()可以将Series对象与DataFrame对象组合在一起,并沿指定轴完成连接操作。
学生必须理解:
python
axis=0
与:
python
axis=1
产生的结果完全不同。
重点2:axis参数
axis=0
按行方向堆叠。
例如:
1月份销售数据:
| 商品 | 销量 |
|---|---|
| A | 100 |
| B | 80 |
2月份销售数据:
| 商品 | 销量 |
|---|---|
| A | 120 |
| B | 90 |
合并以后:
| 商品 | 销量 |
|---|---|
| A | 100 |
| B | 80 |
| A | 120 |
| B | 90 |
本质是:
增加数据记录。
axis=1
按列方向拼接。
例如:
基本信息:
| 姓名 | 年龄 |
|---|---|
| 张三 | 20 |
| 李四 | 21 |
成绩:
| 数学 | 英语 |
|---|---|
| 90 | 88 |
| 85 | 92 |
拼接后:
| 姓名 | 年龄 | 数学 | 英语 |
|---|---|---|---|
| 张三 | 20 | 90 | 88 |
| 李四 | 21 | 85 | 92 |
本质是:
增加数据字段。
重点3:combine_first()
combine_first()不是简单的上下或左右拼接,而是利用另一个DataFrame中对应位置的数据,对当前DataFrame中的缺失数据进行补充。
PPT将其描述为为数据"打补丁":如果调用者对象存在缺失数据,可以用另一个DataFrame中的对应数据进行填充。
(二)教学难点
难点1:merge()和concat()的区别
学生容易认为:
"两个表合起来都一样。"
需要重点区分:
merge():
根据业务主键建立关系。
例如:
text
按照学号匹配
而concat():
主要按照行或列方向直接组合。
因此:
text
merge = 匹配
concat = 堆叠
难点2:索引对合并结果的影响
例如:
表A索引:
text
0 1 2 3
表B索引:
text
2 3 4 5
如果直接堆叠:
可能出现:
text
0
1
2
3
2
3
4
5
因此需要理解:
python
ignore_index=True
难点3:重叠合并与普通填充的区别
fillna()通常使用:
- 固定值
- 平均值
- 中位数
进行填充。
而:
python
combine_first()
使用的是:
另一份具有实际业务意义的数据。
因此二者处理思想不同。
四、PPT页码对应
本课建议对应PPT第23---41页。
| PPT页码 | 教学内容 | 教学重点 | 建议教学方式 |
|---|---|---|---|
| P23 | 4.3堆叠合并数据导入 | 堆叠合并概念 | 案例导入 |
| P24 | concat()函数 | 参数及基本语法 | 教师讲授 |
| P25 | concat基本案例 | axis=0 | 代码演示 |
| P26-P27 | keys、ignore_index、axis=1 | 索引与横向拼接 | 对比演示 |
| P28-P30 | concatenate() | NumPy数组拼接 | 代码演示 |
| P31 | append() | DataFrame追加 | 对比讲解 |
| P32-P33 | 4.4重叠合并 | "打补丁"思想 | 案例导入 |
| P34 | combine()语法 | func、fill_value、overwrite | 参数讲授 |
| P35-P39 | combine()案例 | 比较、填充和组合 | 代码演示 |
| P40 | combine_first()原理 | 缺失值补充 | 教师讲授 |
| P41 | combine_first()案例 | 对应位置补充 | 综合演示 |
PPT明确把堆叠合并分为concat()、concatenate()和append()三部分,并把重叠合并分为combine()与combine_first()。
五、教学导入(10分钟)
案例:一家连锁超市的月度销售数据
教师展示两个文件。
文件1:sales_january.csv
| 订单编号 | 商品 | 销售额 |
|---|---|---|
| O001 | 牛奶 | 120 |
| O002 | 面包 | 80 |
| O003 | 水果 | 150 |
文件2:sales_february.csv
| 订单编号 | 商品 | 销售额 |
|---|---|---|
| O101 | 牛奶 | 135 |
| O102 | 面包 | 90 |
| O103 | 水果 | 170 |
教师提问:
如果我们需要分析第一季度所有订单,是按照订单编号进行merge,还是把两个月的数据直接接起来?
引导学生回答:
两个文件字段完全一致,只是记录属于不同月份,因此更适合:
python
pd.concat()
教师继续给出第二种情况:
系统A中的用户数据:
| 用户ID | 手机号 |
|---|---|
| U01 | 13800000001 |
| U02 | 空 |
备份系统中的用户数据:
| 用户ID | 手机号 |
|---|---|
| U01 | 13800000001 |
| U02 | 13900000002 |
提问:
第二个表能不能帮助第一个表补上U02的手机号?
由此引出:
python
combine_first()
六、知识讲授
6.1 堆叠合并数据
6.1.1 什么是堆叠合并?
堆叠合并适用于:
多个数据表具有相同或相近结构,需要沿某个方向组合。
典型场景:
场景1:月份数据
text
1月销售数据
+
2月销售数据
+
3月销售数据
形成:
text
第一季度销售数据
场景2:部门数据
text
北京分公司
+
上海分公司
+
广州分公司
形成:
text
全国销售数据
6.2 Pandas的concat()函数
PPT给出的基本语法为:
python
pd.concat(
objs,
axis=0,
join="outer",
ignore_index=False
)
其中PPT重点列出了objs、axis、join和ignore_index等参数。
6.2.1 objs参数
表示需要连接的Series或DataFrame对象。
例如:
python
pd.concat([df1, df2])
注意:
对象需要放在:
python
[]
中。
6.2.2 axis参数
axis=0
默认值:
python
axis=0
表示按行方向连接。
代码:
python
result = pd.concat(
[df1, df2],
axis=0
)
案例代码
python
import pandas as pd
a = pd.DataFrame({
"A": ["A0", "A1", "A2", "A3"],
"B": ["B0", "B1", "B2", "B3"],
"C": ["C0", "C1", "C2", "C3"],
"D": ["D0", "D1", "D2", "D3"]
}, index=[0, 1, 2, 3])
b = pd.DataFrame({
"A": ["A4", "A5", "A6", "A7"],
"B": ["B4", "B5", "B6", "B7"],
"C": ["C4", "C5", "C6", "C7"],
"D": ["D4", "D5", "D6", "D7"]
}, index=[2, 3, 4, 5])
result = pd.concat([a, b])
print(result)
PPT例4-6的结果中,DataFrame a的数据位于上方,b的数据接在下方。
6.3 索引重复问题
观察结果:
text
0
1
2
3
2
3
4
5
发现:
索引:
text
2
3
重复。
教师提问:
数据已经合并成功,但索引为什么看起来不规范?
因为:
concat()默认保留原来的索引。
解决方法:
python
ignore_index=True
例如:
python
result = pd.concat(
[a, b],
ignore_index=True
)
新的索引:
text
0
1
2
3
4
5
6
7
PPT也指出,如果希望合并后索引依次递增,可设置ignore_index=True。
6.4 keys参数
如果希望知道每部分数据来自哪里:
可以添加:
python
keys=["x", "y"]
代码:
python
result = pd.concat(
[a, b],
keys=["x", "y"]
)
print(result)
结果形成分层索引:
text
x 0
1
2
3
y 2
3
4
5
作用:
保留数据来源信息。
例如:
python
keys=["1月", "2月"]
方便后续分析每个月的数据。
6.5 axis=1横向合并
代码:
python
result = pd.concat(
[a, b],
axis=1
)
此时:
不是增加数据行。
而是:
增加数据列。
教师强调:
text
axis=0 → 行增加
axis=1 → 列增加
如果两个DataFrame索引无法对应,对应位置会产生NaN。PPT在横向连接示例中特别指出,不存在的数据位置会使用NaN填充。
6.6 join参数
concat()还可以通过:
python
join="outer"
或者:
python
join="inner"
控制字段范围。
outer
取并集。
inner
取交集。
可以联系上一课时:
text
outer = 并集
inner = 交集
帮助学生建立统一认知。
6.7 NumPy的concatenate()函数
PPT指出,concatenate()主要用于数组拼接,默认沿axis=0连接。
基本语法:
python
np.concatenate(
[arr1, arr2],
axis=0
)
纵向拼接
python
import numpy as np
arr1 = np.arange(9).reshape(3, 3)
arr2 = np.arange(9).reshape(3, 3)
result = np.concatenate(
[arr1, arr2],
axis=0
)
print(result)
两个:
text
3行×3列
数组变成:
text
6行×3列
横向拼接
python
result = np.concatenate(
[arr1, arr2],
axis=1
)
结果:
text
3行×6列
6.8 append()方法
PPT中介绍:
python
a.append(b)
可以沿行方向追加DataFrame。
其效果类似:
python
pd.concat([a, b])
PPT同时提示,append()未来将被取缔,实际教学中可重点掌握concat()。
因此课堂教学可以强调:
本节认识append()的思想即可,实际实验统一优先使用concat()。
七、4.4 重叠合并数据
7.1 什么是重叠合并?
教师展示:
数据A:
| 编号 | 电话 |
|---|---|
| U01 | 13800000001 |
| U02 | NaN |
数据B:
| 编号 | 电话 |
|---|---|
| U01 | 13800000001 |
| U02 | 13900000002 |
希望结果:
| 编号 | 电话 |
|---|---|
| U01 | 13800000001 |
| U02 | 13900000002 |
这不是增加行。
也不是增加列。
而是:
利用第二组数据中对应位置的有效数据补充第一组数据中的缺失位置。
PPT把这种操作定义为当两组数据索引完全或部分重合、且存在缺失数据时,通过对应数据进行组合。
7.2 combine()方法
基本语法:
python
df1.combine(
df2,
func
)
主要参数:
func
规定两个DataFrame如何组合。
fill_value
规定缺失值处理方式。
overwrite
决定如何处理调用者独有字段。
7.3 combine()案例1------按列选择
PPT例4-10使用匿名函数比较两列数据总和,选择较小的一列。
python
import pandas as pd
df1 = pd.DataFrame({
"A": [0, 0],
"B": [4, 4]
})
df2 = pd.DataFrame({
"A": [1, 1],
"B": [3, 3]
})
take_smaller = lambda x, y: (
x if x.sum() < y.sum() else y
)
result = df1.combine(
df2,
take_smaller
)
print(result)
7.4 combine()案例2------对应位置取最小值
代码:
python
import pandas as pd
import numpy as np
df1 = pd.DataFrame({
"A": [5, 0],
"B": [2, 4]
})
df2 = pd.DataFrame({
"A": [1, 1],
"B": [3, 3]
})
result = df1.combine(
df2,
np.minimum
)
print(result)
结果:
每个对应位置选择较小值。
7.5 fill_value参数
如果数据存在缺失:
可以:
python
fill_value=-5
例如:
python
result = df1.combine(
df2,
take_smaller,
fill_value=-5
)
PPT例4-12即使用fill_value=-5处理缺失位置。
7.6 combine_first()方法
这是本课需要学生真正掌握的第二个重点方法。
基本语法:
python
df1.combine_first(df2)
逻辑:
text
如果df1有值
→ 保留df1
如果df1缺失
→ 尝试使用df2对应位置的值
PPT明确指出,combine_first()既不是行连接,也不是列连接,而是用参数DataFrame的数据为当前DataFrame中的缺失位置"打补丁"。
示例
python
import pandas as pd
import numpy as np
x = pd.DataFrame([
[np.nan, 3.0, 5.0],
[-4.6, np.nan, np.nan],
[np.nan, 7.0, np.nan]
])
y = pd.DataFrame([
[-42.6, np.nan, -8.2],
[-5.0, 1.6, 4.0]
], index=[1, 2])
result = x.combine_first(y)
print(result)
PPT例4-15即使用该方式进行重叠填充,并指出不存在的对应数据仍以NaN表示。
八、merge、concat、combine_first对比
这是本课必须帮助学生建立起来的知识框架。
| 方法 | 核心思想 | 典型场景 |
|---|---|---|
| merge() | 根据主键匹配 | 学生表+成绩表 |
| concat() | 沿行或列堆叠 | 1月数据+2月数据 |
| combine() | 按规则组合对应数据 | 两组指标比较 |
| combine_first() | 用另一数据补缺失位置 | 主数据+备用数据 |
教师总结口诀:
text
有主键,要匹配 → merge
结构一样,要追加 → concat
数据重叠,要比较 → combine
缺失位置,要补丁 → combine_first
九、课堂案例分析
案例:三家门店销售数据集成
store_A.csv
| 日期 | 商品 | 销售额 |
|---|---|---|
| 2026-01-01 | 牛奶 | 1200 |
| 2026-01-01 | 面包 | 800 |
store_B.csv
| 日期 | 商品 | 销售额 |
|---|---|---|
| 2026-01-01 | 牛奶 | 1000 |
| 2026-01-01 | 面包 | 750 |
store_C.csv
| 日期 | 商品 | 销售额 |
|---|---|---|
| 2026-01-01 | 牛奶 | 1350 |
| 2026-01-01 | 面包 | 900 |
问题:
问题1
三个门店字段完全相同,希望形成公司总销售明细,应使用:
python
pd.concat()
问题2
希望合并后重新生成索引:
python
ignore_index=True
问题3
希望保留门店来源:
python
keys=["A店", "B店", "C店"]
十、实验3:多门店销售数据集成实验
1. 实验名称
多门店销售数据堆叠与缺失信息补充实验
2. 实验目的
-
掌握
concat()的基本使用方法。 -
掌握纵向和横向数据拼接。
-
掌握
ignore_index参数。 -
了解
concatenate()数组拼接。 -
掌握
combine_first()数据补充方法。 -
能够根据业务场景选择合理的数据合并方法。
3. 实验环境
Python 3.x
Jupyter Notebook
主要库:
python
import pandas as pd
import numpy as np
十一、学生代码文件
建议文件名:
text
chapter4_lesson3_data_integration.py
完整代码:
python
import pandas as pd
import numpy as np
# ==============================
# 一、读取三家门店数据
# ==============================
store_a = pd.read_csv("store_A.csv")
store_b = pd.read_csv("store_B.csv")
store_c = pd.read_csv("store_C.csv")
print("A店数据:")
print(store_a)
print("B店数据:")
print(store_b)
print("C店数据:")
print(store_c)
# ==============================
# 二、纵向堆叠
# ==============================
all_sales = pd.concat(
[store_a, store_b, store_c],
ignore_index=True
)
print("三家门店合并结果:")
print(all_sales)
# ==============================
# 三、增加数据来源
# ==============================
store_a["门店"] = "A店"
store_b["门店"] = "B店"
store_c["门店"] = "C店"
all_sales_source = pd.concat(
[store_a, store_b, store_c],
ignore_index=True
)
print("增加门店来源后的数据:")
print(all_sales_source)
# ==============================
# 四、保存结果
# ==============================
all_sales_source.to_csv(
"all_store_sales.csv",
index=False,
encoding="utf-8-sig"
)
# ==============================
# 五、NumPy数组拼接
# ==============================
arr1 = np.array([
[100, 200],
[300, 400]
])
arr2 = np.array([
[500, 600],
[700, 800]
])
vertical = np.concatenate(
[arr1, arr2],
axis=0
)
horizontal = np.concatenate(
[arr1, arr2],
axis=1
)
print("纵向数组拼接:")
print(vertical)
print("横向数组拼接:")
print(horizontal)
# ==============================
# 六、缺失信息补充
# ==============================
main_data = pd.read_csv(
"customer_main.csv",
index_col="用户ID"
)
backup_data = pd.read_csv(
"customer_backup.csv",
index_col="用户ID"
)
print("补充前:")
print(main_data)
customer_complete = main_data.combine_first(
backup_data
)
print("补充后:")
print(customer_complete)
customer_complete.to_csv(
"customer_complete.csv",
encoding="utf-8-sig"
)
十二、实验数据文件
文件1:store_A.csv
csv
日期,商品,销售额
2026-01-01,牛奶,1200
2026-01-01,面包,800
2026-01-02,水果,1500
文件2:store_B.csv
csv
日期,商品,销售额
2026-01-01,牛奶,1000
2026-01-01,面包,750
2026-01-02,水果,1300
文件3:store_C.csv
csv
日期,商品,销售额
2026-01-01,牛奶,1350
2026-01-01,面包,900
2026-01-02,水果,1600
文件4:customer_main.csv
csv
用户ID,姓名,手机号,城市
U001,张三,13800000001,北京
U002,李四,,上海
U003,王五,13700000003,
U004,赵六,,广州
文件5:customer_backup.csv
csv
用户ID,姓名,手机号,城市
U001,张三,13800000001,北京
U002,李四,13900000002,上海
U003,王五,13700000003,深圳
U004,赵六,13600000004,广州
十三、实验步骤
步骤1:读取门店数据
分别读取:
text
store_A.csv
store_B.csv
store_C.csv
查看:
python
head()
shape
columns
步骤2:纵向合并
使用:
python
pd.concat()
完成三家门店数据合并。
步骤3:处理索引
比较:
python
pd.concat([store_a, store_b])
与:
python
pd.concat(
[store_a, store_b],
ignore_index=True
)
记录两次结果区别。
步骤4:增加门店来源
增加字段:
python
store_a["门店"] = "A店"
其他门店同理。
再次合并。
步骤5:数组拼接
分别设置:
python
axis=0
与:
python
axis=1
观察结果维度变化。
步骤6:用户信息补充
读取:
text
customer_main.csv
customer_backup.csv
使用:
python
combine_first()
补充:
- 手机号
- 城市
步骤7:保存集成结果
输出:
text
all_store_sales.csv
customer_complete.csv
十四、实验结果分析
学生完成以下问题。
1. 三个门店原始数据分别有多少行?
A店:____行
B店:____行
C店:____行
2. concat以后共有多少行?
________行。
3. ignore_index=True的作用是什么?
答:
4. axis=0和axis=1有什么区别?
答:
5. customer_main中哪些字段存在缺失?
答:
6. combine_first以后哪些缺失数据得到补充?
答:
十五、教师讲稿
导入讲稿
同学们,上节课我们学习了merge和join,这两个方法解决的核心问题是什么?是"匹配"。例如学生基本信息表和学生成绩表,我们按照学号把属于同一个学生的信息匹配起来。
但是今天我们来看另外一种情况。假设公司每天都会生成一个销售文件,一月份一个文件,二月份又一个文件。这两个文件的字段完全一样,我们并不需要根据某个主键把左右信息对应起来,而是希望把二月份的数据直接接到一月份下面。这种处理方法就叫堆叠合并。
因此大家首先要建立一个非常重要的判断:数据集成不是只有一种方法。不同的数据结构,要选择不同的合并方式。
concat讲稿
大家看Pandas中的concat函数。concat可以理解成"把几个数据对象接起来"。
首先观察axis参数。当axis等于0时,我们沿行方向连接,也就是把第二张表放到第一张表下面。所以原来每张表有4条记录,两张表连接以后就有8条记录。
这里大家注意一个现象:为什么索引出现了两个2和两个3?
原因非常简单,concat默认保留每个DataFrame原来的索引。对于计算机来说,这并不是错误,但对于我们后续的数据管理来说不够规范。
因此如果希望重新生成0、1、2、3这样的连续索引,可以设置ignore_index等于True。
axis讲稿
接下来大家一定要分清axis。
axis等于0,我们通常可以理解为"向下接",增加的是记录。
axis等于1,可以理解为"向右接",增加的是字段。
所以以后看到concat,首先不要急着写代码,先问自己一句:我要增加的是数据行,还是数据列?
concatenate讲稿
Pandas处理的主要是DataFrame,而如果我们操作的是NumPy数组,就可以使用concatenate。
它和concat的思想非常相似,也通过axis控制方向。
两个3行3列数组沿axis=0拼接以后变成6行3列;沿axis=1拼接以后变成3行6列。
这里重点不是记函数名字,而是理解"轴"的概念。
重叠合并导入讲稿
下面我们看另外一个问题。
假设企业的主客户数据库中某个客户电话号码丢失了,但是备份数据库中恰好存在这个电话号码。
我们是不是可以简单把两个表上下拼起来?不可以。
是不是需要增加一列?也不需要。
我们真正希望做的是:主表有数据的位置保持原来的数据,主表缺失的位置,用备用表对应位置的数据进行补充。
这就是重叠合并的思想。
combine_first讲稿
combine_first这个函数大家可以形象地理解成"打补丁"。
它首先查看调用这个函数的DataFrame。如果这个位置已经有有效数据,那么原来的数据优先保留;如果这个位置是缺失值,就到另一个DataFrame中寻找相同位置的数据,如果能够找到,就使用另一个DataFrame的数据补充。
因此它特别适合主数据和备用数据融合、历史记录补充等场景。
课堂收束讲稿
今天学完以后,大家至少要能够回答三个问题。
第一,有共同主键、需要按照业务关系匹配的时候,用什么?------merge。
第二,两批结构相似的数据希望上下接起来,用什么?------concat。
第三,主数据中有缺失,希望利用另一份数据补充,用什么?------combine_first。
如果能够先判断数据之间的关系,再选择函数,那么这一章的数据集成就真正学会了。
十六、课堂总结
本课可以归纳为四个关键词。
1. 堆叠
python
pd.concat()
2. 数组拼接
python
np.concatenate()
3. 规则组合
python
combine()
4. 数据补丁
python
combine_first()
最终形成第四章目前的知识关系:
text
数据集成
│
├── 主键合并
│ ├── merge()
│ └── join()
│
├── 堆叠合并
│ ├── concat()
│ ├── concatenate()
│ └── append()
│
└── 重叠合并
├── combine()
└── combine_first()
十七、课后作业
(一)理论题
-
什么是堆叠合并数据?
-
concat()中axis=0和axis=1有什么区别? -
ignore_index=True有什么作用? -
concat()和merge()有什么区别? -
什么是重叠合并?
-
combine()与combine_first()有什么区别?
(二)实践题
现有三个文件:
text
sales_01.csv
sales_02.csv
sales_03.csv
分别记录1---3月销售数据。
要求:
- 使用
concat()合并三个文件。 - 添加"月份"字段。
- 重新建立连续索引。
- 保存为
quarter1_sales.csv。 - 检查是否存在缺失数据。
- 如果另外提供
backup_sales.csv,尝试利用重叠合并思想补充缺失数据。
十八、实验报告模板
《Python数据预处理》实验报告
实验名称
多来源数据堆叠与重叠合并实验
一、实验目的
二、实验环境
Python版本:________________
开发环境:________________
使用库:________________
三、实验数据
本实验使用的数据文件:
- store_A.csv
- store_B.csv
- store_C.csv
- customer_main.csv
- customer_backup.csv
四、实验内容
1. 数据读取
程序代码:
python
运行结果:
2. concat纵向合并
程序代码:
python
运行结果:
3. 索引处理
程序代码:
python
结果分析:
4. NumPy数组拼接
程序代码:
python
结果分析:
5. combine_first缺失信息补充
程序代码:
python
运行结果:
五、实验结果对比
| 操作 | 处理前 | 处理后 |
|---|---|---|
| 门店数据行数 | ||
| 索引 | ||
| 客户缺失手机号数量 | ||
| 客户缺失城市数量 |
六、问题分析
- 为什么本实验中的门店销售数据使用concat而不是merge?
答:
- 为什么combine_first适合补充备用数据?
答:
- 如果主数据和备用数据同一位置都有不同的有效值,combine_first应该优先保留哪一个?结合实验结果说明。
答:
七、实验总结
通过本实验,我掌握了:
实验中遇到的问题:
解决方法:
《Python数据预处理》
第四章 数据集成
第4课时教学设计
主题:集成方法认识、数据集拆分与虚拟姓名数据综合实战
一、课程基本信息
课程名称:《Python数据预处理》
所属章节:第四章 数据集成
课时安排:第4课时(2学时)
教学主题:
集成学习基本思想、数据集拆分与多源姓名数据综合集成
本课主要内容:
- 认识Scikit-learn机器学习库
- 理解集成学习基本思想
- 认识Bagging、Boosting、随机森林、AdaBoost、GBDT
- 理解训练集、验证集和测试集
- 掌握
train_test_split()基本使用方法 - 了解留出法、K折交叉验证和Bootstrap
- 综合运用
concat()完成行、列数据合并 - 综合运用
merge()完成主键合并 - 比较
inner与outer连接结果 - 保存集成后的数据文件
教学方式:
- 理论讲授
- 图示讲解
- 案例分析
- Python代码演示
- 综合实验
- 任务驱动教学
教学环境:
- Python 3.x
- Anaconda
- Jupyter Notebook
- Pandas
- NumPy
- Scikit-learn
二、本课教学目标
(一)知识目标
-
了解Scikit-learn机器学习库的基本作用。
-
理解集成学习的基本思想。
-
了解常见集成学习方法:
- Bagging
- Boosting
- Random Forest
- AdaBoost
- GBDT
-
理解训练集、验证集和测试集的作用。
-
理解数据集拆分的目的。
-
掌握
train_test_split()的基本使用方法。 -
了解三种数据集拆分思想:
- 留出法
- K折交叉验证
- Bootstrap自助法
- 综合掌握:
python
pd.concat()
和:
python
pd.merge()
的使用方法。
(二)能力目标
通过本课学习,使学生能够:
-
根据数据分析任务判断为什么需要划分训练数据和测试数据。
-
使用
train_test_split()完成训练集和测试集拆分。 -
能够根据数据结构判断应该采用堆叠合并还是主键合并。
-
能够创建多个DataFrame对象。
-
能够使用
concat()完成行方向和列方向的数据组合。 -
能够根据
subject_id使用merge()完成多数据源匹配。 -
能够区分
inner和outer连接结果。 -
能够将处理结果保存为CSV文件。
-
能够形成较完整的数据集成处理流程。
(三)素养目标
-
培养学生"训练数据与评价数据相互独立"的数据分析意识。
-
培养学生从业务目标出发选择数据集成方法的习惯。
-
培养学生对程序运行结果进行验证,而不是只关注"代码能否运行"的严谨意识。
-
培养学生规范保存中间结果和最终数据的工程习惯。
-
建立"单一方法解决有限问题,多种方法组合完成复杂任务"的数据处理思想。
三、教学重点与难点
(一)教学重点
重点1:理解集成学习的基本思想
PPT将集成学习的目标概括为:
将多个基估计器的预测结果组合起来,从而获得比单个估计器更好的泛化能力和鲁棒性。
本课程为《Python数据预处理》,因此不要求学生推导算法公式。
重点让学生理解:
text
单个模型
↓
多个模型
↓
结果组合
↓
提高整体预测能力
重点2:数据集为什么需要拆分
学生需要理解:
机器学习不能:
text
用同一批数据训练
↓
再用完全相同的数据评价
而应该:
text
原始数据
↓
拆分
↓
训练集 + 测试集
PPT指出,测试集应尽量与训练集互斥,即测试样本尽量不在训练集中出现。
重点3:train_test_split()
掌握基本代码:
python
from sklearn.model_selection import train_test_split
以及:
python
X_train, X_test, y_train, y_test = train_test_split(
X,
y,
test_size=0.2,
random_state=1234
)
PPT例4-21即使用test_size=0.2将数据拆分为训练集和测试集。
重点4:综合区分concat()和merge()
本节综合实验要求学生真正掌握:
text
结构相同,直接堆叠
→ concat()
存在共同业务键,需要匹配
→ merge()
重点5:inner与outer
要求学生能够解释:
python
how="inner"
表示:
只保留两个数据表都匹配成功的数据。
而:
python
how="outer"
表示:
尽可能保留两张表的全部键。
(二)教学难点
难点1:数据"集成"与"集成学习"的关系
前三课时学习的数据集成是:
text
多个数据源
↓
合并成为新的数据集
4.5中的集成学习是:
text
多个学习器
↓
组合预测结果
二者并不是同一个操作。
教师需要明确:
前者重点是"数据的组合",后者重点是"模型结果的组合"。本PPT将集成学习作为扩展内容介绍,用于帮助学生认识"集成"思想在后续机器学习中的应用。
难点2:训练集与测试集的作用
学生常见错误认识:
"测试数据越多,模型越好。"
实际上:
训练数据用于学习。
测试数据用于评价。
二者承担不同作用。
难点3:理解inner和outer的数据差异
例如:
data1中的subject_id:
text
1 2 3 4 5
data2中的subject_id:
text
4 5 6 7 8
那么:
inner:
text
4 5
outer:
text
1 2 3 4 5 6 7 8
这一集合关系需要学生真正理解,而不是机械记忆参数。
四、PPT页码对应
本课对应PPT P44---P75,P76---P77可作为章节总结使用。
| PPT页码 | 教学内容 | 教学定位 |
|---|---|---|
| P44-P45 | sklearn与集成学习 | 理论认识 |
| P46-P47 | Bagging | 扩展认识 |
| P48-P49 | Boosting | 扩展认识 |
| P50-P51 | 随机森林 | 重点了解 |
| P52-P53 | AdaBoost | 扩展认识 |
| P54-P56 | GBDT | 扩展认识 |
| P57-P58 | 数据集拆分原则、原因 | 重点讲授 |
| P59 | 留出法 | 了解 |
| P60 | K折交叉验证 | 了解 |
| P61 | Bootstrap | 了解 |
| P62-P64 | 数据集拆分实例 | 代码演示 |
| P65-P67 | 虚拟姓名数据任务说明 | 综合实验导入 |
| P68 | concat任务分析 | 知识复习 |
| P69 | merge任务分析 | 知识复习 |
| P70 | 创建DataFrame | 实验 |
| P71-P72 | concat行列合并 | 实验 |
| P73-P74 | merge主键合并 | 实验 |
| P75 | 查询与保存 | 实验总结 |
| P76-P77 | 本章总结 | 课堂总结 |
PPT中的虚拟姓名数据实战明确要求完成DataFrame创建、行列堆叠、主键合并、内外连接以及结果保存。
五、建议教学时间分配
本课共90分钟。
| 教学环节 | 时间 |
|---|---|
| 课程导入 | 5分钟 |
| sklearn与集成学习思想 | 15分钟 |
| 数据集拆分 | 20分钟 |
| 虚拟姓名案例分析 | 10分钟 |
| 综合代码实验 | 30分钟 |
| 结果分析与总结 | 10分钟 |
教学建议:
Bagging、Boosting、RF、AdaBoost、GBDT不宜分别展开复杂推导。
将主要时间留给:
text
数据集拆分
+
虚拟姓名数据综合实验
六、教学导入(5分钟)
案例:一个模型准确率达到100%,可信吗?
教师提出情境:
假设我们有100名学生的数据。
建立一个"是否通过考试"的预测模型。
程序输出:
text
准确率:100%
教师提问:
模型准确率100%,是不是意味着模型一定非常优秀?
让学生讨论。
然后补充:
如果:
text
用这100条数据训练模型
又:
text
用完全相同的100条数据测试模型
那么这个结果不一定能够说明模型具有处理新数据的能力。
引出:
数据为什么需要拆分?
再进一步:
如果一个模型能力有限,能不能让多个模型一起工作?
引出:
集成学习。
七、知识讲授
7.1 认识Scikit-learn
Scikit-learn简称:
text
sklearn
PPT中介绍了其常用算法模块,包括:
- linear_model
- tree
- neural_network
- naive_bayes
- SVM
- neighbors
同时包含:
- 分类
- 回归
- 聚类
- 随机森林
等机器学习方法。
教师讲解
在前面课程中,我们主要使用:
python
pandas
numpy
处理数据。
而:
python
sklearn
主要用于:
text
机器学习建模
所以我们可以理解为:
text
Pandas
↓
准备和处理数据
Scikit-learn
↓
利用处理好的数据建立模型
7.2 什么是集成学习?
教师给出一个生活案例。
假设有一道题:
学生A回答:
text
正确
学生B回答:
text
正确
学生C回答:
text
错误
如果进行投票:
text
2票正确
1票错误
最终判断:
text
正确
这体现一种思想:
多个判断结果组合以后,可能比单个判断更加可靠。
PPT将集成学习概括为多个基分类器共同完成学习任务,通过投票等方式组合结果。
7.3 Bagging
基本思想
PPT中的Bagging采用:
text
自助采样
即:
text
有放回抽样
流程:
text
原始训练数据
↓
多次随机抽样
↓
数据集1 → 模型1
数据集2 → 模型2
数据集3 → 模型3
↓
结果组合
↓
最终预测
PPT指出,每次采样训练一个基分类器,经过多次采样得到多个分类器,然后依据表决原则组合分类结果。
示例认识
PPT使用鸢尾花数据演示:
python
from sklearn.ensemble import BaggingClassifier
并结合:
python
KNeighborsClassifier()
构造Bagging模型。
本课要求:
认识代码结构即可,不要求独立完成调参。
7.4 Boosting
Boosting与Bagging不同。
Bagging:
text
多个模型相对独立
Boosting:
text
前一个模型的结果
↓
影响后一个模型
PPT指出,Boosting通过重新赋予样本权重,迭代训练多个基分类器,每轮样本权值分布依赖上一轮分类结果,代表算法包括AdaBoost和GBDT。
教师类比
第一次考试:
某学生:
text
数学错误较多
那么第二阶段复习:
text
增加数学错题权重
第三阶段:
继续重点关注:
text
仍然容易出错的问题
这就是Boosting思想的直观理解。
7.5 随机森林
PPT把随机森林RF描述为Bagging算法的进化版,并使用CART决策树作为弱学习器。
可以简单理解为:
text
很多棵决策树
↓
分别进行判断
↓
组合所有树的结果
↓
得到最终结果
PPT示例比较了:
- 决策树
- 随机森林
- 极限随机树
的准确率。
7.6 AdaBoost与GBDT
AdaBoost
PPT将AdaBoost作为一种分类提升方法介绍,并使用:
python
AdaBoostClassifier
进行示例。
GBDT
GBDT:
text
Gradient Boosting Decision Tree
即:
text
梯度提升决策树
PPT将其放在Boosting家族中介绍,并通过多棵决策树迭代组合得到最终结果。
本节记忆关系
根据PPT总结:
text
Bagging + 决策树
=
随机森林
AdaBoost + 决策树
=
提升树
Gradient Boosting + 决策树
=
GBDT
八、数据集拆分
8.1 为什么拆分数据?
教师提出:
如果模型只会记住训练过的数据:
遇到新的数据可能无法正确判断。
因此:
需要预留一部分:
text
模型没有见过的数据
进行测试。
基本结构
text
原始数据集
↓
拆分
↓
训练集 测试集
Train Test
↓ ↓
训练模型 评价模型
PPT介绍机器学习中通常将数据分为训练集、验证集和测试集。
8.2 训练集、验证集、测试集
训练集 Train
用于:
text
让模型学习规律
验证集 Validation
用于:
text
参数选择
模型调整
测试集 Test
用于:
text
最终评价模型
8.3 数据拆分比例
PPT介绍一种常见思路:
text
80%
训练
20%
测试
即:
text
8 : 2
PPT同时指出,不同数据量可使用不同划分方式,小样本情况下也可使用:
text
6 : 2 : 2
分别作为:
text
训练集
验证集
测试集
8.4 留出法
Hold-out。
基本思想:
一次性将原始数据划分为:
text
训练集
+
测试集
PPT指出,应尽可能保持训练集和测试集的数据分布一致,常取约2/3或4/5作为训练数据。
8.5 K折交叉验证
K-fold。
例如:
将数据分为:
text
第1份
第2份
第3份
第4份
第5份
即:
text
K=5
第一次:
text
第1份做验证
2、3、4、5做训练
第二次:
text
第2份做验证
1、3、4、5做训练
依次进行。
PPT介绍了将数据划分为K个分区并轮流作为验证集的思想。
8.6 Bootstrap自助法
Bootstrap特点:
text
有放回抽样
适用于:
text
数据量较少
PPT将其定位为数据集较小、难以有效划分训练集和测试集时的一种方法。
九、train_test_split()代码演示
创建简单数据
python
import pandas as pd
data = pd.DataFrame({
"学习时间": [1,2,3,4,5,6,7,8,9,10],
"练习次数": [2,2,3,4,4,5,6,6,7,8],
"是否通过": [0,0,0,0,1,1,1,1,1,1]
})
X = data[["学习时间", "练习次数"]]
y = data["是否通过"]
拆分数据
python
from sklearn.model_selection import train_test_split
X_train, X_test, y_train, y_test = train_test_split(
X,
y,
test_size=0.2,
random_state=1234
)
查看结果
python
print("训练特征:")
print(X_train)
print("测试特征:")
print(X_test)
print("训练标签:")
print(y_train)
print("测试标签:")
print(y_test)
参数说明
test_size
python
test_size=0.2
表示:
20%的数据用于测试。
random_state
python
random_state=1234
用于控制随机拆分过程,使实验在相同条件下能够重复得到相同拆分结果。
十、课堂案例导入------探索虚拟姓名数据
PPT 4.6提出:
大数据时代很多数据是分散和零碎的,案例给出三组姓名相关数据,通过合并操作形成新的数据结果。主要任务包括DataFrame创建、命名、合并、查询和显示。
十一、任务分析
数据1
包含:
text
subject_id
first_name
last_name
数据2
同样包含:
text
subject_id
first_name
last_name
数据3
包含:
text
subject_id
test_id
问题1
data1和data2结构相同。
应该:
python
pd.concat()
问题2
姓名数据和测试编号具有共同字段:
text
subject_id
应该:
python
pd.merge()
十二、实验4:探索虚拟姓名数据
1. 实验名称
虚拟姓名多源数据综合集成实验
2. 实验目的
-
掌握DataFrame数据创建方法。
-
掌握
concat()行方向合并。 -
掌握
concat()列方向合并。 -
掌握
merge()主键合并。 -
掌握
inner连接。 -
掌握
outer连接。 -
掌握CSV文件保存。
-
综合复习本章主要数据集成方法。
3. 实验环境
操作系统:
Windows 10 / Windows 11
Python:
Python 3.x
开发环境:
Jupyter Notebook
主要库:
python
import numpy as np
import pandas as pd
PPT案例使用Win10 64位、Anaconda、Jupyter Notebook、NumPy和Pandas。
十三、实验数据
本实验不需要外部原始CSV,直接在代码中构造三组虚拟数据。
数据1
python
raw_data_1 = {
"subject_id": ["1", "2", "3", "4", "5"],
"first_name": [
"Alex",
"Amy",
"Allen",
"Alice",
"Ayoung"
],
"last_name": [
"Anderson",
"Ackerman",
"Ali",
"Aoni",
"Atiches"
]
}
数据2
python
raw_data_2 = {
"subject_id": ["4", "5", "6", "7", "8"],
"first_name": [
"Billy",
"Brian",
"Bran",
"Bryce",
"Betty"
],
"last_name": [
"Bonder",
"Black",
"Balwner",
"Brice",
"Btisan"
]
}
数据3
python
raw_data_3 = {
"subject_id": [
"1","2","3","4","5",
"7","8","9","10","11"
],
"test_id": [
51,15,15,61,16,
14,15,1,61,16
]
}
这些数据与PPT任务实现中的三组元数据一致。
十四、学生代码文件
建议文件名:
text
chapter4_lesson4_name_integration.py
完整代码如下。
python
import numpy as np
import pandas as pd
# ======================================
# 1. 创建原始数据
# ======================================
raw_data_1 = {
"subject_id": ["1", "2", "3", "4", "5"],
"first_name": [
"Alex",
"Amy",
"Allen",
"Alice",
"Ayoung"
],
"last_name": [
"Anderson",
"Ackerman",
"Ali",
"Aoni",
"Atiches"
]
}
raw_data_2 = {
"subject_id": ["4", "5", "6", "7", "8"],
"first_name": [
"Billy",
"Brian",
"Bran",
"Bryce",
"Betty"
],
"last_name": [
"Bonder",
"Black",
"Balwner",
"Brice",
"Btisan"
]
}
raw_data_3 = {
"subject_id": [
"1", "2", "3", "4", "5",
"7", "8", "9", "10", "11"
],
"test_id": [
51, 15, 15, 61, 16,
14, 15, 1, 61, 16
]
}
# ======================================
# 2. 创建DataFrame
# ======================================
data1 = pd.DataFrame(
raw_data_1,
columns=[
"subject_id",
"first_name",
"last_name"
]
)
data2 = pd.DataFrame(
raw_data_2,
columns=[
"subject_id",
"first_name",
"last_name"
]
)
data3 = pd.DataFrame(
raw_data_3,
columns=[
"subject_id",
"test_id"
]
)
print("data1:")
print(data1)
print("\ndata2:")
print(data2)
print("\ndata3:")
print(data3)
# ======================================
# 3. 按行堆叠
# ======================================
all_data = pd.concat(
[data1, data2],
ignore_index=True
)
print("\ndata1和data2按行合并:")
print(all_data)
# ======================================
# 4. 按列合并
# ======================================
all_data_col = pd.concat(
[data1, data2],
axis=1
)
print("\ndata1和data2按列合并:")
print(all_data_col)
# ======================================
# 5. all_data与data3按subject_id合并
# ======================================
name_test = pd.merge(
all_data,
data3,
on="subject_id"
)
print("\n姓名与测试数据合并:")
print(name_test)
# ======================================
# 6. data1和data2进行inner连接
# ======================================
inner_result = pd.merge(
data1,
data2,
on="subject_id",
how="inner",
suffixes=("_data1", "_data2")
)
print("\ninner连接结果:")
print(inner_result)
# ======================================
# 7. data1和data2进行outer连接
# ======================================
outer_result = pd.merge(
data1,
data2,
on="subject_id",
how="outer",
suffixes=("_data1", "_data2")
)
print("\nouter连接结果:")
print(outer_result)
# ======================================
# 8. 保存结果
# ======================================
all_data.to_csv(
"all_name_data.csv",
index=False,
encoding="utf-8-sig"
)
name_test.to_csv(
"name_test_data.csv",
index=False,
encoding="utf-8-sig"
)
outer_result.to_csv(
"name_outer_result.csv",
index=False,
encoding="utf-8-sig"
)
print("\n文件保存完成。")
PPT中实际任务依次进行了行方向concat()、列方向concat(axis=1)、按照subject_id进行merge()、内连接和外连接,最后将处理结果写入CSV。
十五、实验步骤
步骤1:创建三个DataFrame
运行:
python
print(data1)
print(data2)
print(data3)
观察:
三个数据集字段是否相同。
步骤2:判断数据关系
填写:
data1与data2:
text
字段结构:
________________
适合:
________________
正确思路:
字段结构相同。
适合堆叠合并。
步骤3:按行合并
使用:
python
all_data = pd.concat(
[data1, data2],
ignore_index=True
)
观察:
数据行数变化。
步骤4:按列合并
python
all_data_col = pd.concat(
[data1, data2],
axis=1
)
比较:
text
axis=0
与:
text
axis=1
产生的结果。
步骤5:按照subject_id主键合并
python
pd.merge(
all_data,
data3,
on="subject_id"
)
思考:
为什么这里不使用concat?
步骤6:执行inner
python
pd.merge(
data1,
data2,
on="subject_id",
how="inner"
)
记录:
共有多少个subject_id匹配成功。
步骤7:执行outer
python
pd.merge(
data1,
data2,
on="subject_id",
how="outer"
)
记录:
共有多少个不同subject_id。
步骤8:保存文件
保存:
text
all_name_data.csv
name_test_data.csv
name_outer_result.csv
十六、实验结果分析
问题1
data1共有多少条数据?
答:
text
5条
问题2
data2共有多少条数据?
答:
text
5条
问题3
按行concat以后共有多少条数据?
答:
text
10条
问题4
data1和data2有哪些共同subject_id?
答:
text
4
5
因此inner连接主要保留:
text
subject_id = 4
subject_id = 5
问题5
outer连接包含哪些subject_id?
text
1
2
3
4
5
6
7
8
问题6
为什么outer结果会出现NaN?
因为某些subject_id只存在于其中一个DataFrame中,另一DataFrame无法提供对应字段信息。
十七、教师讲稿
第一部分:课程导入
同学们,前三次课我们解决的都是一个问题:不同来源的数据到底怎样合并起来。我们已经学习了按照主键匹配的merge、按照行列方向连接的concat,以及利用另外一份数据补充缺失位置的combine_first。
今天是第四章的最后一次课。我们要完成两件事情。
第一,向后看一步,认识这些处理好的数据进入机器学习以后还会经历什么,其中非常重要的一步就是数据集拆分和集成学习。
第二,把前三节课学习的合并方法重新放入一个完整案例中,完成虚拟姓名数据的综合集成。
第二部分:集成学习讲稿
大家注意,"数据集成"和"集成学习"虽然都有"集成"两个字,但是处理对象不一样。
数据集成解决的是:
多个数据源怎样组合成一份数据。
集成学习解决的是:
多个学习器或者多个模型怎样组合预测结果。
大家可以把集成学习理解成多人共同做决策。如果只有一个模型,它可能会判断错误;如果有多个具有差异的模型,再通过投票或加权等方式形成最终结果,整体能力可能得到提升。
因此这里我们重点理解思想,不要求大家推导复杂数学公式。
第三部分:Bagging讲稿
Bagging最重要的两个关键词是什么?
第一个:
随机抽样。
第二个:
并行地训练多个模型。
它会从原始训练数据中进行多次有放回抽样,每次得到一组训练数据,然后训练一个模型。
最终多个模型共同参与判断。
随机森林就是大家今后经常遇到的一种典型集成模型,它和Bagging思想关系非常密切。
第四部分:Boosting讲稿
Boosting与Bagging最大的区别,是模型之间不是完全独立的。
Boosting会不断关注前一轮没有处理好的样本。
可以理解为:
第一次做题,发现几个题错了。
第二次学习的时候,提高这些错题的关注程度。
如果还有题继续错,下一轮继续重点处理。
所以Boosting是一种逐步改进的思想。
AdaBoost和GBDT都是这一类方法。
第五部分:数据集拆分讲稿
接下来这个内容非常重要。
假设我给大家100道题,然后告诉你考试题就是这100道题。
你把答案全部背下来。
考试的时候还是这100道题。
最后你考了100分。
这个100分能不能证明你真正掌握知识?
不能。
模型也是同样的问题。
如果模型只在已经学习过的数据上进行测试,我们无法真正判断它处理新数据的能力。
所以必须从原始数据中留出一部分模型没有参与训练的数据,用来测试模型。
这就是训练集和测试集拆分的核心意义。
第六部分:train_test_split讲稿
在Scikit-learn里面,最常用的数据拆分函数之一就是train_test_split。
大家重点看这个参数:
python
test_size=0.2
0.2代表20%。
也就是说:
80%的数据进入训练集。
20%的数据进入测试集。
再看:
python
random_state=1234
它用于控制随机过程,使我们再次运行代码时,能够在相同条件下得到相同的数据划分,便于实验复现。
第七部分:综合实验导入讲稿
下面进入本章最后一个案例。
我们现在有三组数据。
data1和data2记录的是姓名信息,它们结构相同。
所以大家想一想:
如果我要把两个姓名数据放到一张大表里,应该使用什么?
对,concat。
但是data3不一样。
data3中只有:
subject_id和test_id。
我们希望给姓名数据匹配测试编号。
这时不是简单上下拼接,而是要通过共同的subject_id找到对应关系。
所以应该用:
merge。
这就是为什么大家不能看到两个表就随便选择一个函数。
选择什么函数,由数据之间的关系决定。
第八部分:inner与outer讲稿
大家观察data1:
subject_id从1到5。
data2:
subject_id是4、5、6、7、8。
两个表共同出现的是:
4和5。
所以:
inner只留下4和5。
而outer希望尽可能保留两个表的所有数据,因此最终出现:
1到8。
但是有些编号只在一边出现,另一边没有相应姓名数据,所以产生NaN。
请大家记住:
NaN在这种情况下不是代码错误。
它反映的是:
数据源之间没有成功匹配的信息。
第九部分:课堂收束讲稿
到这里,第四章实际上可以用四句话总结。
第一:
不同来源的数据需要集成。
第二:
有共同业务主键,需要匹配,用merge。
第三:
结构相似,需要上下或左右堆叠,用concat。
第四:
模型训练之前还需要合理拆分训练集和测试集,而多个模型也可以通过集成学习形成更强的预测能力。
真正掌握数据预处理,不是记住多少个函数,而是面对一组数据时能够判断:
它存在什么问题?
数据之间是什么关系?
应该选择哪种处理方法?
十八、课堂总结
第四章完整知识框架:
text
数据集成
│
├── 1. 数据集成概述
│ ├── 信息孤岛
│ ├── ETL / ELT
│ ├── 冗余属性
│ └── 实体识别
│
├── 2. 主键合并
│ ├── merge()
│ ├── join()
│ ├── inner
│ ├── left
│ ├── right
│ └── outer
│
├── 3. 堆叠合并
│ ├── concat()
│ ├── concatenate()
│ └── append()
│
├── 4. 重叠合并
│ ├── combine()
│ └── combine_first()
│
├── 5. 集成方法认识
│ ├── Bagging
│ ├── Boosting
│ ├── Random Forest
│ ├── AdaBoost
│ └── GBDT
│
└── 6. 数据集拆分
├── Hold-out
├── K-fold
└── Bootstrap
PPT本章总结也明确归纳了三类数据合并方式,并在最后加入sklearn集成学习与数据集拆分。
十九、课堂思考题
-
数据集成和集成学习有什么区别?
-
为什么不能使用全部数据同时进行训练和测试?
-
test_size=0.2是什么意思? -
Bagging和Boosting最核心的思想差异是什么?
-
data1和data2为什么适合使用concat?
-
data1和data3为什么更适合使用merge?
-
inner连接为什么只有subject_id=4和5?
-
outer连接为什么会产生NaN?
-
如果要求"所有姓名都必须保留",应该优先考虑哪种连接方式?
-
如果两个文件只是1月和2月销售明细,应该使用merge还是concat?为什么?
二十、课后作业
(一)理论题
-
什么是集成学习?
-
简述Bagging的基本思想。
-
简述Boosting的基本思想。
-
什么是训练集和测试集?
-
为什么测试集不能参与模型训练?
-
简述留出法和K折交叉验证的区别。
-
比较
concat()和merge()的适用场景。
(二)实践题
提供三个数据文件:
text
student_a.csv
student_b.csv
student_score.csv
其中:
student_a.csv:
text
student_id
name
class
student_b.csv:
text
student_id
name
class
student_score.csv:
text
student_id
score
要求:
-
读取三个文件。
-
使用
concat()合并student_a和student_b。 -
重新建立连续索引。
-
使用
merge()按照student_id匹配成绩。 -
分别执行inner和outer连接。
-
比较结果。
-
将最终数据保存为:
text
student_integrated.csv
二十一、实验报告模板
《Python数据预处理》实验报告
实验名称
探索虚拟姓名数据------多源数据综合集成
姓名
班级
学号
一、实验目的
二、实验环境
Python版本:
开发环境:
主要库:
三、实验数据说明
data1
字段:
数据规模:
data2
字段:
数据规模:
data3
字段:
数据规模:
四、实验过程
1. 创建DataFrame
代码:
python
运行结果:
2. data1与data2按行合并
代码:
python
合并前行数:
合并后行数:
3. data1与data2按列合并
代码:
python
结果:
4. 按subject_id进行主键合并
代码:
python
结果:
5. inner连接
代码:
python
匹配成功的subject_id:
6. outer连接
代码:
python
全部subject_id:
7. 保存数据
代码:
python
生成文件:
五、实验结果对比
| 操作 | 数据行数 | 数据列数 | 是否出现NaN |
|---|---|---|---|
| data1 | |||
| data2 | |||
| concat行合并 | |||
| concat列合并 | |||
| inner连接 | |||
| outer连接 |
六、结果分析
问题1
为什么data1与data2可以直接进行行方向concat?
答:
问题2
为什么姓名数据与test_id数据需要按照subject_id进行merge?
答:
问题3
inner和outer产生的数据数量为什么不同?
答:
问题4
outer中的NaN说明了什么?
答:
七、实验总结
本实验掌握的主要方法:
我认为最容易混淆的知识:
我的解决方法:
八、拓展思考
如果现在增加第四组数据:
text
subject_id
age
gender
应该如何将年龄、性别信息加入当前姓名数据?
请写出你的处理思路和核心代码:
python