Python 数据分析与可视化 Day 10 - 数据合并与连接
✅ 今日目标
- 理解 Pandas 中数据合并的 4 种常用方式:
concat
、merge
、join
、combine
- 掌握内连接、外连接、左连接、右连接等操作方式
- 掌握按列对齐、按索引对齐的区别
- 为后续数据整合、特征拼接等建模任务做准备
📚 一、concat 合并(按行/列拼接)
df1 = pd.DataFrame({"姓名": ["张三", "李四"], "成绩": [85, 90]})
df2 = pd.DataFrame({"姓名": ["王五", "赵六"], "成绩": [70, 78]})# 纵向合并(行堆叠)
df_concat_row = pd.concat([df1, df2], ignore_index=True)# 横向合并(列拼接)
df_concat_col = pd.concat([df1, df2], axis=1)
📚 二、merge 合并(按列匹配)
df_left = pd.DataFrame({"学号": [1, 2, 3],"姓名": ["张三", "李四", "王五"]
})
df_right = pd.DataFrame({"学号": [2, 3, 4],"成绩": [90, 80, 60]
})# 默认 inner join(交集)
df_inner = pd.merge(df_left, df_right, on="学号")# 左连接:保留左表所有数据
df_left_join = pd.merge(df_left, df_right, on="学号", how="left")# 外连接:并集合并,空值补 NaN
df_outer = pd.merge(df_left, df_right, on="学号", how="outer")
📚 三、join(按索引连接)
df1 = pd.DataFrame({"成绩": [85, 90]}, index=["张三", "李四"])
df2 = pd.DataFrame({"班级": ["A", "B"]}, index=["张三", "王五"])# 使用 join 合并(按 index 对齐)
df_joined = df1.join(df2, how="outer")
📚 四、combine_first(数据补全)
df1 = pd.DataFrame({"姓名": ["张三", "李四", "王五"],"成绩": [85, None, 90]
})
df2 = pd.DataFrame({"姓名": ["张三", "李四", "王五"],"成绩": [None, 88, None]
})# 用 df2 中的非空数据补全 df1
df1.set_index("姓名", inplace=True)
df2.set_index("姓名", inplace=True)
df_combined = df1.combine_first(df2)
🧪 今日练习建议
-
准备两个表(如学生信息表 + 成绩表),练习
merge
的不同 join 模式 -
构造相同索引的两个表,练习
join
的用法(按索引合并) -
使用
concat
实现表格的上下或左右拼接 -
使用
combine_first
补全缺失值(融合多个数据源)import pandas as pdprint("✅ 初始化数据...")# 模拟 学生信息表 df_students = pd.DataFrame({"学号": [1001, 1002, 1003, 1004],"姓名": ["张三", "李四", "王五", "赵六"],"性别": ["男", "女", "男", "女"] })# 模拟 成绩表(部分学生) df_scores = pd.DataFrame({"学号": [1002, 1003, 1005],"成绩": [88, 75, 92] })# 模拟 班级信息(姓名为索引) df_classes = pd.DataFrame({"班级": ["A班", "B班", "C班"] }, index=["张三", "李四", "王五"])# 模拟 第三方成绩补充表 df_scores_backup = pd.DataFrame({"学号": [1001, 1002, 1003],"成绩": [85, None, 78] })# ========= 一、merge 合并演示 =========print("\n🔗 merge(inner join,默认):") df_inner = pd.merge(df_students, df_scores, on="学号", how="inner") print(df_inner)print("\n🔗 merge(left join):") df_left = pd.merge(df_students, df_scores, on="学号", how="left") print(df_left)print("\n🔗 merge(outer join):") df_outer = pd.merge(df_students, df_scores, on="学号", how="outer") print(df_outer)# ========= 二、concat 行列拼接 =========print("\n📚 concat 行拼接:") df_part1 = df_students.iloc[:2] df_part2 = df_students.iloc[2:] df_concat = pd.concat([df_part1, df_part2], ignore_index=True) print(df_concat)print("\n📚 concat 列拼接:") df_concat_col = pd.concat([df_part1.reset_index(drop=True), df_scores.head(2).reset_index(drop=True)], axis=1) print(df_concat_col)# ========= 三、join 按索引合并 =========print("\n🔗 join(按姓名索引):") df_named = df_students.set_index("姓名") df_joined = df_named.join(df_classes, how="left") print(df_joined)# ========= 四、combine_first 用于数据补全 =========print("\n🧩 combine_first(成绩补全):") df_score_main = df_scores.set_index("学号") df_score_backup = df_scores_backup.set_index("学号") df_combined = df_score_main.combine_first(df_score_backup) print(df_combined)# (可选)保存结果 df_left.to_csv("data/merged_left.csv", index=False) df_combined.to_csv("data/combined_scores.csv")print("\n✅ 合并与连接示例完成,结果已输出并保存。")
运行输出:
✅ 初始化数据...🔗 merge(inner join,默认):学号 姓名 性别 成绩 0 1002 李四 女 88 1 1003 王五 男 75🔗 merge(left join):学号 姓名 性别 成绩 0 1001 张三 男 NaN 1 1002 李四 女 88.0 2 1003 王五 男 75.0 3 1004 赵六 女 NaN🔗 merge(outer join):学号 姓名 性别 成绩 0 1001 张三 男 NaN 1 1002 李四 女 88.0 2 1003 王五 男 75.0 3 1004 赵六 女 NaN 4 1005 NaN NaN 92.0📚 concat 行拼接:学号 姓名 性别 0 1001 张三 男 1 1002 李四 女 2 1003 王五 男 3 1004 赵六 女📚 concat 列拼接:学号 姓名 性别 学号 成绩 0 1001 张三 男 1002 88 1 1002 李四 女 1003 75🔗 join(按姓名索引):学号 性别 班级 姓名 张三 1001 男 A班 李四 1002 女 B班 王五 1003 男 C班 赵六 1004 女 NaN🧩 combine_first(成绩补全):成绩 学号 1001 85.0 1002 88.0 1003 75.0 1005 92.0✅ 合并与连接示例完成,结果已输出并保存。
🧾 今日总结
方法 | 用途 | 特点 |
---|---|---|
concat() | 多表拼接 | 行/列级拼接 |
merge() | 类似 SQL join | 支持主键连接 |
join() | 按索引合并 | 简洁易用 |
combine_first() | 数据补全 | 常用于多源合并 |
数据整合是建模准备中的关键一环,推荐熟练掌握
merge
与concat
的灵活使用。