查看全课大纲(第 60 / 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.实战:通过移动设备行为数据预测性别和年龄
数据规整(2) -- 数据连接merge
约 14 分钟
数据连接 merge
小象实战讲义 · Python数据分析实战
在数据分析工作中,数据往往分散在多个表格或数据源中。例如,用户信息在一个表格,购买记录在另一个表格,产品信息又在第三个表格。要将这些信息整合起来进行分析,就需要用到数据连接操作。本节将学习 Pandas 中强大的 merge() 函数,它能够像数据库的 JOIN 操作一样,根据共同的列将不同的 DataFrame 连接起来。
💡 核心导读
- 数据连接的概念:理解
merge()与之前学过的concat()的区别,掌握基于“键”(列)的连接思想。 - 四种连接方式:学习外连接、内连接、左连接和右连接的区别与应用场景。
- 灵活指定连接键:掌握当列名不同或需要按索引连接时的参数设置。
- 处理重复列名:了解连接后重复列名的自动处理机制与自定义后缀方法。
1. merge() 的基本概念
merge() 是 Pandas 中用于数据连接的核心函数。它与之前学习的 concat() 有本质区别:
concat():是简单的拼接,将数据沿某个轴(横向或纵向)堆叠在一起,不关心内容关联。merge():是基于一个或多个“键”(通常是列名)将不同 DataFrame 的行关联起来,类似于数据库的表连接(JOIN)操作。
为什么需要 merge? 想象一个实际场景:一个表格记录员工信息(姓名、部门),另一个表格记录员工技能(姓名、技能)。要分析每个部门员工的技能分布,就需要根据“姓名”这个共同的列将两个表格连接起来。
merge() 默认会将两个 DataFrame 中列名相同的列作为连接键。你也可以通过参数显式指定。
import pandas as pd
# 创建两个示例 DataFrame
staff_df = pd.DataFrame([{'姓名': '张三', '部门': '研发部'},
{'姓名': '李四', '部门': '财务部'},
{'姓名': '赵六', '部门': '市场部'}])
student_df = pd.DataFrame([{'姓名': '张三', '专业': '计算机'},
{'姓名': '李四', '专业': '会计'},
{'姓名': '王五', '专业': '市场营销'}])
print("员工信息表:")
print(staff_df)
print("\n学生信息表:")
print(student_df)员工信息表:
姓名 部门
0 张三 研发部
1 李四 财务部
2 赵六 市场部
学生信息表:
姓名 专业
0 张三 计算机
1 李四 会计
2 王五 市场营销观察这两个表格:
- 张三和李四同时出现在两个表中
- 赵六只在员工表中(可能不是学生,或是实习生但未登记专业)
- 王五只在学生表中(可能未在该公司实习)
2. 四种连接方式详解
merge() 通过 how 参数指定连接方式,这与数据库的 JOIN 类型完全对应。
2.1 外连接 (outer)
外连接取两个 DataFrame 的并集。只要数据出现在任一个表中,就会出现在结果中,缺失的部分用 NaN(空值)填充。
import pandas as pd
# 重新创建数据(确保每个代码块自包含)
staff_df = pd.DataFrame([{'姓名': '张三', '部门': '研发部'},
{'姓名': '李四', '部门': '财务部'},
{'姓名': '赵六', '部门': '市场部'}])
student_df = pd.DataFrame([{'姓名': '张三', '专业': '计算机'},
{'姓名': '李四', '专业': '会计'},
{'姓名': '王五', '专业': '市场营销'}])
# 外连接
result_outer = pd.merge(staff_df, student_df, how='outer', on='姓名')
print("外连接结果(并集):")
print(result_outer)外连接结果(并集):
姓名 部门 专业
0 张三 研发部 计算机
1 李四 财务部 会计
2 王五 NaN 市场营销
3 赵六 市场部 NaN结果解读:
- 张三、李四:两个表都有,信息完整
- 赵六:只有员工信息,专业为空
- 王五:只有学生信息,部门为空
2.2 内连接 (inner)
内连接取两个 DataFrame 的交集。只保留在两个表中都出现的记录。
import pandas as pd
staff_df = pd.DataFrame([{'姓名': '张三', '部门': '研发部'},
{'姓名': '李四', '部门': '财务部'},
{'姓名': '赵六', '部门': '市场部'}])
student_df = pd.DataFrame([{'姓名': '张三', '专业': '计算机'},
{'姓名': '李四', '专业': '会计'},
{'姓名': '王五', '专业': '市场营销'}])
# 内连接
result_inner = pd.merge(staff_df, student_df, how='inner', on='姓名')
print("内连接结果(交集):")
print(result_inner)内连接结果(交集):
姓名 部门 专业
0 张三 研发部 计算机
1 李四 财务部 会计结果解读:只保留了张三和李四,因为只有他们同时出现在两个表中。
2.3 左连接 (left)
左连接以左边的 DataFrame 为基准,保留左边的所有记录。右边表中没有匹配的记录,对应字段填 NaN。
import pandas as pd
staff_df = pd.DataFrame([{'姓名': '张三', '部门': '研发部'},
{'姓名': '李四', '部门': '财务部'},
{'姓名': '赵六', '部门': '市场部'}])
student_df = pd.DataFrame([{'姓名': '张三', '专业': '计算机'},
{'姓名': '李四', '专业': '会计'},
{'姓名': '王五', '专业': '市场营销'}])
# 左连接(以staff_df为基准)
result_left = pd.merge(staff_df, student_df, how='left', on='姓名')
print("左连接结果(保留左边所有记录):")
print(result_left)左连接结果(保留左边所有记录):
姓名 部门 专业
0 张三 研发部 计算机
1 李四 财务部 会计
2 赵六 市场部 NaN结果解读:
- 员工表的三条记录全部保留
- 赵六没有匹配的专业信息,所以专业列为空
- 学生表中的王五(不在员工表中)不出现
2.4 右连接 (right)
右连接以右边的 DataFrame 为基准,与左连接正好相反。
import pandas as pd
staff_df = pd.DataFrame([{'姓名': '张三', '部门': '研发部'},
{'姓名': '李四', '部门': '财务部'},
{'姓名': '赵六', '部门': '市场部'}])
student_df = pd.DataFrame([{'姓名': '张三', '专业': '计算机'},
{'姓名': '李四', '专业': '会计'},
{'姓名': '王五', '专业': '市场营销'}])
# 右连接(以student_df为基准)
result_right = pd.merge(staff_df, student_df, how='right', on='姓名')
print("右连接结果(保留右边所有记录):")
print(result_right)右连接结果(保留右边所有记录):
姓名 部门 专业
0 张三 研发部 计算机
1 李四 财务部 会计
2 王五 NaN 市场营销结果解读:
- 学生表的三条记录全部保留
- 王五没有匹配的部门信息,所以部门列为空
- 员工表中的赵六(不在学生表中)不出现
3. 高级连接技巧
3.1 处理列名不同的情况
当两个 DataFrame 中作为连接键的列名不同时,可以使用 left_on 和 right_on 参数分别指定。
import pandas as pd
# 创建列名不同的两个DataFrame
staff_df = pd.DataFrame([{'员工姓名': '张三', '部门': '研发部'},
{'员工姓名': '李四', '部门': '财务部'}])
student_df = pd.DataFrame([{'学生姓名': '张三', '专业': '计算机'},
{'学生姓名': '李四', '专业': '会计'}])
# 连接列名不同时
result_diff_col = pd.merge(staff_df, student_df,
left_on='员工姓名',
right_on='学生姓名',
how='inner')
print("列名不同时的连接结果:")
print(result_diff_col)列名不同时的连接结果:
员工姓名 部门 学生姓名 专业
0 张三 研发部 张三 计算机
1 李四 财务部 李四 会计注意:两个连接键列都会保留在结果中。如果要去掉重复列,可以后续处理。
3.2 处理重复列名
当两个 DataFrame 中有相同列名(但不是连接键)时,Pandas 会自动添加后缀 _x 和 _y 来区分。
import pandas as pd
# 创建两个都有"地址"列的DataFrame
staff_df = pd.DataFrame([{'姓名': '张三', '部门': '研发部', '地址': '天津'},
{'姓名': '李四', '部门': '财务部', '地址': '北京'},
{'姓名': '赵六', '部门': '市场部', '地址': '上海'}])
student_df = pd.DataFrame([{'姓名': '张三', '专业': '计算机', '地址': '天津'},
{'姓名': '李四', '专业': '会计', '地址': '上海'},
{'姓名': '王五', '专业': '市场营销', '地址': '广州'}])
# 连接时,非连接键的相同列名会自动加后缀
result_with_dup = pd.merge(staff_df, student_df,
how='left',
on='姓名')
print("有重复列名时的连接结果(自动加后缀):")
print(result_with_dup)有重复列名时的连接结果(自动加后缀):
姓名 部门 地址_x 专业 地址_y
0 张三 研发部 天津 计算机 天津
1 李四 财务部 北京 会计 上海
2 赵六 市场部 上海 NaN NaN后缀说明:
地址_x:来自左边(staff_df)的地址列(实习城市)地址_y:来自右边(student_df)的地址列(家乡)
你可以使用 suffixes 参数自定义后缀:
import pandas as pd
staff_df = pd.DataFrame([{'姓名': '张三', '部门': '研发部', '地址': '天津'},
{'姓名': '李四', '部门': '财务部', '地址': '北京'}])
student_df = pd.DataFrame([{'姓名': '张三', '专业': '计算机', '地址': '天津'},
{'姓名': '李四', '专业': '会计', '地址': '上海'}])
# 使用自定义后缀
result_custom_suffix = pd.merge(staff_df, student_df,
how='left',
on='姓名',
suffixes=('_员工', '_学生'))
print("使用自定义后缀:")
print(result_custom_suffix)使用自定义后缀:
姓名 部门 地址_员工 专业 地址_学生
0 张三 研发部 天津 计算机 天津
1 李四 财务部 北京 会计 上海3.3 按索引连接
有时连接键不是列,而是 DataFrame 的索引。这时可以使用 left_index=True 和 right_index=True 参数。
import pandas as pd
# 创建DataFrame并设置索引
staff_df = pd.DataFrame({'部门': ['研发部', '财务部', '市场部']},
index=['张三', '李四', '赵六'])
student_df = pd.DataFrame({'专业': ['计算机', '会计', '市场营销']},
index=['张三', '李四', '王五'])
print("员工表(索引为姓名):")
print(staff_df)
print("\n学生表(索引为姓名):")
print(student_df)
# 按索引连接
result_by_index = pd.merge(staff_df, student_df,
left_index=True,
right_index=True,
how='outer')
print("\n按索引连接的结果(外连接):")
print(result_by_index)员工表(索引为姓名):
部门
张三 研发部
李四 财务部
赵六 市场部
学生表(索引为姓名):
专业
张三 计算机
李四 会计
王五 市场营销
按索引连接的结果(外连接):
部门 专业
张三 研发部 计算机
李四 财务部 会计
王五 NaN 市场营销
赵六 市场部 NaN4. merge() 的两种调用方式
Pandas 提供了两种等价的调用方式:
- 函数式调用:
pd.merge(left_df, right_df, ...) - 方法式调用:
left_df.merge(right_df, ...)
两种方式参数相同,选择哪种取决于个人习惯。方法式调用更符合面向对象思维,能清晰看出以哪个 DataFrame 为基准。
import pandas as pd
staff_df = pd.DataFrame([{'姓名': '张三', '部门': '研发部'},
{'姓名': '李四', '部门': '财务部'}])
student_df = pd.DataFrame([{'姓名': '张三', '专业': '计算机'},
{'姓名': '李四', '专业': '会计'}])
# 两种调用方式等价
result1 = pd.merge(staff_df, student_df, how='inner', on='姓名')
result2 = staff_df.merge(student_df, how='inner', on='姓名')
print("函数式调用结果:")
print(result1)
print("\n方法式调用结果:")
print(result2)函数式调用结果:
姓名 部门 专业
0 张三 研发部 计算机
1 李四 财务部 会计
方法式调用结果:
姓名 部门 专业
0 张三 研发部 计算机
1 李四 财务部 会计📝 动手练一练
- 概念辨析:假设你有两个 DataFrame,A 表有 100 行,B 表有 80 行。它们有 60 行基于共同键匹配。
- 如果使用内连接,结果大约有多少行?
- 如果使用左连接(以 A 为左表),结果有多少行?
- 如果使用外连接,结果最多可能有多少行?
👉 点击查看参考答案
- 内连接:约 60 行(取交集,只保留匹配的行)
- 左连接:100 行(保留左表所有行,右表无匹配的填 NaN)
- 外连接:最多 120 行(100 + 80 - 60 = 120,这是并集的行数)
- 动手实践:创建两个 DataFrame,一个记录产品信息(产品ID、产品名称、价格),一个记录销售记录(销售ID、产品ID、销售量、销售日期)。使用 merge 连接这两个表,计算每个产品的总销售额(价格 × 销售量)。
👉 点击查看参考答案
import pandas as pd
# 产品信息
products = pd.DataFrame({
'产品ID': ['P001', 'P002', 'P003'],
'产品名称': ['笔记本', '鼠标', '键盘'],
'价格': [5000, 150, 300]
})
# 销售记录
sales = pd.DataFrame({
'销售ID': ['S001', 'S002', 'S003', 'S004'],
'产品ID': ['P001', 'P002', 'P001', 'P003'],
'销售量': [2, 5, 1, 3],
'销售日期': ['2024-01-10', '2024-01-11', '2024-01-12', '2024-01-13']
})
# 连接两个表
merged_data = pd.merge(sales, products, on='产品ID', how='left')
# 计算销售额
merged_data['销售额'] = merged_data['价格'] * merged_data['销售量']
# 按产品汇总
sales_summary = merged_data.groupby(['产品ID', '产品名称'])['销售额'].sum().reset_index()
print("连接后的数据:")
print(merged_data)
print("\n各产品总销售额:")
print(sales_summary)连接后的数据:
销售ID 产品ID 销售量 销售日期 产品名称 价格 销售额
0 S001 P001 2 2024-01-10 笔记本 5000 10000
1 S002 P002 5 2024-01-11 鼠标 150 750
2 S003 P001 1 2024-01-12 笔记本 5000 5000
3 S004 P003 3 2024-01-13 键盘 300 900
各产品总销售额:
产品ID 产品名称 销售额
0 P001 笔记本 15000
1 P002 鼠标 750
2 P003 键盘 900本章小结
本节深入学习了 Pandas 中数据连接的核心操作 merge()。与简单的 concat() 拼接不同,merge() 是基于共同键的智能连接,是数据分析中整合多源数据的关键技术。
📋 行动清单
- 掌握四种连接方式:理解外连接、内连接、左连接、右连接的区别,能根据分析需求选择合适的方式。
- 练习复杂场景:尝试列名不同、按索引连接、处理重复列名等高级用法,理解每个参数的作用。
- 对比数据库操作:如果你熟悉 SQL,可以对比
merge()与 SQL JOIN 的异同,加深理解。
在实际工作中,数据往往分散在多个系统或文件中。掌握 merge() 就像拥有了数据世界的”粘合剂”,能够将碎片化的信息整合成完整的分析视图,为后续的统计分析、可视化展示和机器学习建模打下坚实基础。
—— 小象教研组
配套资料 · 直接下载
课件、代码、数据集等配套资料全部免费,点击即可直接下载,无需分享或解锁。
- 下载本节课件:数据规整(2) -- 数据连接mergePDF · 293KB
- 下载全套课件打包(第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 数据库