人生苦短,我用 Python

前文传送门:

小白学 Python 数据分析(1):数据分析基础

小白学 Python 数据分析(2):Pandas (一)概述

小白学 Python 数据分析(3):Pandas (二)数据结构 Series

小白学 Python 数据分析(4):Pandas (三)数据结构 DataFrame

小白学 Python 数据分析(5):Pandas (四)基础操作(1)查看数据

小白学 Python 数据分析(6):Pandas (五)基础操作(2)数据选择

小白学 Python 数据分析(7):Pandas (六)数据导入

小白学 Python 数据分析(8):Pandas (七)数据预处理

小白学 Python 数据分析(9):Pandas (八)数据预处理(2)

小白学 Python 数据分析(10):Pandas (九)数据运算

小白学 Python 数据分析(11):Pandas (十)数据分组

小白学 Python 数据分析(12):Pandas (十一)数据透视表(pivot_table)

引言

说到数据表拼接,就不得不提一下 SQL ,对于熟悉 SQL 的同学来讲,这并不是一个难以理解的概念,数据表之间的关系可以分为以下这三种:

一对一

两个表之间的公共列是一对一的。

这里的示例我们就不用图片了,直接使用代码来做展示,原因嘛就是小编懒的画了:

import pandas as pd

df1 = pd.read_excel("table_join_exp.xlsx", sheet_name='Sheet1')
print(df1) # 输出内容
编号 姓名 分数
0 100 小明 96
1 200 小红 48
2 300 小王 72
3 400 小刚 72 df2 = pd.read_excel("table_join_exp.xlsx", sheet_name='Sheet2')
print(df2) # 输出内容
编号 班级
0 100 1
1 200 2
2 300 3
3 400 4

这里可以很直观的看到,这两个表的编号是公共列,并且唯一对应。

如果我们要讲这两个表进行连接操作,需要使用 merge() 方法:

print(pd.merge(df1, df2))

# 输出内容
编号 姓名 分数 班级
0 100 小明 96 1
1 200 小红 48 2
2 300 小王 72 3
3 400 小刚 72 4

在我们使用 merge() 方法的时候, merge() 方法会自动寻找两个表中的公共列,并且自动的进行对应操作。

一对多

两个表之间的公共列不是一对一的,而是其中一个表的公共列是唯一的,另一个表的公共列则会有重复的数据。

import pandas as pd

df1 = pd.read_excel("table_join_exp.xlsx", sheet_name='Sheet1')
print(df1) # 输出内容
编号 姓名 分数
0 100 小明 96
1 200 小红 48
2 300 小王 72
3 400 小刚 72 df3 = pd.read_excel("table_join_exp.xlsx", sheet_name='Sheet3')
print(df3) # 输出内容
编号 分数
0 100 101
1 100 102
2 100 103
3 100 104
4 200 201
5 200 202
6 300 301
7 400 401

从上面这两个 df 中可以看到, df1 中的编号在 df3 中会对应多条数据,我们在对这两个 df 进行连接操作的时候,需要使用属性 on 指明判断的条件:

print(pd.merge(df1, df3, on='编号'))

# 输出内容
编号 姓名 分数_x 分数_y
0 100 小明 96 101
1 100 小明 96 102
2 100 小明 96 103
3 100 小明 96 104
4 200 小红 48 201
5 200 小红 48 202
6 300 小王 72 301
7 400 小刚 72 401

多对多

两个表之间的公共列都是会有重复数据的,相当于是多个一对多。

注意理解多个一对多,这里的逻辑稍微有点绕,小编在第一次接触 SQL 的时候实际上是无法理解的。

我们这里新建一个 df4 ,新增一个编号为 100 的小黑,还是通过编号对 df4 和 df3 进行连接操作:

df4 = pd.read_excel("table_join_exp.xlsx", sheet_name='Sheet4')
print(df4) # 输出结果
编号 姓名 分数
0 100 小明 96
1 100 小黑 100
2 200 小红 48
3 300 小王 72
4 400 小刚 72 print(pd.merge(df4, df3, on='编号'))
编号 姓名 分数_x 分数_y
0 100 小明 96 101
1 100 小明 96 102
2 100 小明 96 103
3 100 小明 96 104
4 100 小黑 100 101
5 100 小黑 100 102
6 100 小黑 100 103
7 100 小黑 100 104
8 200 小红 48 201
9 200 小红 48 202
10 300 小王 72 301
11 400 小刚 72 401

连接方式

学过 SQL 的同学都知道, SQL 中连接分为内连接、左连接、右连接和外连接,同样在 Pandas 也是一样的。

内连接

内连接就是取两个表中公共的部分,我们重新创建一个 df5 ,在 df5 中只有编号 100 和 200 能和前面的数据保持一致:

df5 = pd.read_excel("table_join_exp.xlsx", sheet_name='Sheet5')
print(df5) # 输出结果
编号 姓名 分数
0 100 小明 96
1 100 小黑 100
2 200 小红 48
3 600 想不出来叫啥了1 600
4 700 想不出来叫啥了2 700 # 内连接
print(pd.merge(df5, df3, on='编号', how='inner')) # 输出结果
编号 姓名 分数_x 分数_y
0 100 小明 96 101
1 100 小明 96 102
2 100 小明 96 103
3 100 小明 96 104
4 100 小黑 100 101
5 100 小黑 100 102
6 100 小黑 100 103
7 100 小黑 100 104
8 200 小红 48 201
9 200 小红 48 202

这里 how 属性是用来指定连接类型的。

左连接

左连接就是已左表为基础,右表像左表上拼数据:

# 左连接
print(pd.merge(df5, df3, on='编号', how='left')) # 输出结果
编号 姓名 分数_x 分数_y
0 100 小明 96 101.0
1 100 小明 96 102.0
2 100 小明 96 103.0
3 100 小明 96 104.0
4 100 小黑 100 101.0
5 100 小黑 100 102.0
6 100 小黑 100 103.0
7 100 小黑 100 104.0
8 200 小红 48 201.0
9 200 小红 48 202.0
10 600 想不出来叫啥了1 600 NaN
11 700 想不出来叫啥了2 700 NaN

可以看到,在 df5 中,编号 600 和 700 的两条数据在 df3 中没有,所以 分数_y 的值为 NaN 。

右连接

右连接正好和上面的左连接相反,已右表为基础,左表往右表上拼数据:

# 右连接
print(pd.merge(df5, df3, on='编号', how='right')) # 输出结果
编号 姓名 分数_x 分数_y
0 100 小明 96.0 101
1 100 小黑 100.0 101
2 100 小明 96.0 102
3 100 小黑 100.0 102
4 100 小明 96.0 103
5 100 小黑 100.0 103
6 100 小明 96.0 104
7 100 小黑 100.0 104
8 200 小红 48.0 201
9 200 小红 48.0 202
10 300 NaN NaN 301
11 400 NaN NaN 401

外连接

外连接就是两个表的并集:

# 外连接
print(pd.merge(df5, df3, on='编号', how='outer')) # 输出结果
编号 姓名 分数_x 分数_y
0 100 小明 96.0 101.0
1 100 小明 96.0 102.0
2 100 小明 96.0 103.0
3 100 小明 96.0 104.0
4 100 小黑 100.0 101.0
5 100 小黑 100.0 102.0
6 100 小黑 100.0 103.0
7 100 小黑 100.0 104.0
8 200 小红 48.0 201.0
9 200 小红 48.0 202.0
10 600 想不出来叫啥了1 600.0 NaN
11 700 想不出来叫啥了2 700.0 NaN
12 300 NaN NaN 301.0
13 400 NaN NaN 401.0

纵向拼接

顾名思义,纵向拼接就是在纵向上对两个表进行拼接,当然这需要两个表具有相同的结构,前面我们介绍的拼接方式都在横向上进行拼接。

这里我们再加入一个 df6 ,使用 df5 和 df6 演示纵向拼接,在 Pandas 中使用纵向拼接使用的方法是 concat()

df6 = pd.read_excel("table_join_exp.xlsx", sheet_name='Sheet6')
print(df6) # 输出结果
编号 姓名 分数
0 800 起个名字好难啊 100
1 900 起个名字真的难 200 # 纵向拼接
print(pd.concat([df5, df6])) # 输出结果
编号 姓名 分数
0 100 小明 96
1 100 小黑 100
2 200 小红 48
3 600 想不出来叫啥了1 600
4 700 想不出来叫啥了2 700
0 800 起个名字好难啊 100
1 900 起个名字真的难 200

当我们使用 concat() 以后,发现索引还是保留了原有的索引,看着很不舒服,这时我们可以设置参数 ignore_index ,让其不在保留原有索引,而是生成新的索引:

print(pd.concat([df5, df6], ignore_index=True))

# 输出结果
编号 姓名 分数
0 100 小明 96
1 100 小黑 100
2 200 小红 48
3 600 想不出来叫啥了1 600
4 700 想不出来叫啥了2 700
5 800 起个名字好难啊 100
6 900 起个名字真的难 200

本篇的分享到这里就算结束,如果有 SQL 基础的同学看起来应该毫无压力,没有基础的同学推荐自己动手试一下,很多看着不是很理解的东西一动手就立马打通任督二脉。

示例代码

老规矩,所有的示例代码都会上传至代码管理仓库 Github 和 Gitee 上,方便大家取用。

示例代码-Github

示例代码-Gitee

小白学 Python 数据分析(13):Pandas (十二)数据表拼接的更多相关文章

  1. 小白学 Python 数据分析(15):数据可视化概述

    人生苦短,我用 Python 前文传送门: 小白学 Python 数据分析(1):数据分析基础 小白学 Python 数据分析(2):Pandas (一)概述 小白学 Python 数据分析(3):P ...

  2. 小白学 Python 数据分析(17):Matplotlib(二)基础操作

    人生苦短,我用 Python 前文传送门: 小白学 Python 数据分析(1):数据分析基础 小白学 Python 数据分析(2):Pandas (一)概述 小白学 Python 数据分析(3):P ...

  3. 小白学 Python 数据分析(16):Matplotlib(一)坐标系

    人生苦短,我用 Python 前文传送门: 小白学 Python 数据分析(1):数据分析基础 小白学 Python 数据分析(2):Pandas (一)概述 小白学 Python 数据分析(3):P ...

  4. 小白学 Python 数据分析(18):Matplotlib(三)常用图表(上)

    人生苦短,我用 Python 前文传送门: 小白学 Python 数据分析(1):数据分析基础 小白学 Python 数据分析(2):Pandas (一)概述 小白学 Python 数据分析(3):P ...

  5. 小白学 Python 数据分析(19):Matplotlib(四)常用图表(下)

    人生苦短,我用 Python 前文传送门: 小白学 Python 数据分析(1):数据分析基础 小白学 Python 数据分析(2):Pandas (一)概述 小白学 Python 数据分析(3):P ...

  6. 小白学 Python 数据分析(20):pyecharts 概述

    人生苦短,我用 Python 前文传送门: 小白学 Python 数据分析(1):数据分析基础 小白学 Python 数据分析(2):Pandas (一)概述 小白学 Python 数据分析(3):P ...

  7. 小白学 Python 数据分析(21):pyecharts 好玩的图表(系列终篇)

    人生苦短,我用 Python 前文传送门: 小白学 Python 数据分析(1):数据分析基础 小白学 Python 数据分析(2):Pandas (一)概述 小白学 Python 数据分析(3):P ...

  8. 小白学 Python 数据分析(11):Pandas (十)数据分组

    人生苦短,我用 Python 前文传送门: 小白学 Python 数据分析(1):数据分析基础 小白学 Python 数据分析(2):Pandas (一)概述 小白学 Python 数据分析(3):P ...

  9. 小白学 Python 数据分析(3):Pandas (二)数据结构 Series

    在家为国家做贡献太无聊,不如跟我一起学点 Python 顺便问一下,你们都喜欢什么什么样的文章封面图,老用这一张感觉有点丑 人生苦短,我用 Python 前文传送门: 小白学 Python 数据分析( ...

随机推荐

  1. centos7_安装jira7

    centos7 安装jira7 参考文档:http://www.cnblogs.com/kevingrace/p/7608813.html 1.准备环境 centos7 memory:8G stora ...

  2. JSP中request对象常用方法汇总

    setAttribute(String name,Object):设置名字为name的request的参数值 getAttribute(String name):返回由name指定的属性值 getAt ...

  3. 二十一、NFS服务

    文件系统是基于存储设备的,比如硬盘,并且包含文件物理位置的维护.文件系统也可以说是虚拟数据或网络数据存储的方法,比如NFS.我是这样理解的:首先,什么是文件系统,这里我们已经明确了,就是组织的一种形式 ...

  4. addEventListener和onclick的区别

    onclick只出现一次alert:我是click2[很正常第一次click事件会被第二次所覆盖],但是addEventListener却可以先后运行,不会被覆盖[正如:它允许给一个事件注册多个监听器 ...

  5. 区别 new function(){} 和 function(){}()

    只要 new 表达式之后的 constructor 返回(return)一个引用对象(数组,对象,函数等),都将覆盖new创建的匿名对象,如果返回(return)一个原始类型(无 return 时其实 ...

  6. python调用存储过程失败返回1787错误

    (1787, 'When @@GLOBAL.ENFORCE_GTID_CONSISTENCY = 1, the statements CREATE TEMPORARY TABLE and DROP T ...

  7. QuickSort(快速排序)原理及C++代码实现

    快速排序可以说是最重要的排序,其中延伸的思想和技巧非常值得我们学习. 快速排序也使用了分治的思想,原理如下: 分解:数组A[p..r]被划分为两个(可能为空)子数组A[p..q-1]和A[q+1..r ...

  8. numpy中的ndarray与pandas中的series、dataframe的转换

    一个ndarray是一个多维同类数据容器.每一个数组有一个dtype属性,用来描述数组的数据类型. Series是一种一维数组型对象,包含了一个值序列,并且包含了数据标签----索引(index). ...

  9. [LC] 45. Jump Game II

    Given an array of non-negative integers, you are initially positioned at the first index of the arra ...

  10. java 内存溢出-与gc

    感谢原作者 在日常中我们经常遇到这样的错误:java.lang.OutOfMemoryError: Java heap space. 但是除了heap space 的OutOfMemoryError, ...