一文让你记住Pyspark下DataFrame的7种的Join 效果

2024-08-25 07:08

本文主要是介绍一文让你记住Pyspark下DataFrame的7种的Join 效果,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

最近看到了一片好文,虽然很简单,但是配上的插图可以让人很好的记住Pyspark 中的多种Join 类型和实际的效果。原英文链接 Introduction to Pyspark join types - Blog | luminousmen 。

假设使用如下的两个DataFrame 来进行展示

heroes_data = [('Deadpool', 3), ('Iron man', 1),('Groot', 7),
]
race_data = [('Kryptonian', 5), ('Mutant', 3), ('Human', 1), 
]
heroes = spark.createDataFrame(heroes_data, ['name', 'id'])
races = spark.createDataFrame(race_data, ['race', 'id'])

实际的上的数据展示效果如下:

+--------+---+           +----------+---+
|    name| id|           |      race| id|
+--------+---+           +----------+---+
|Deadpool|  3|           |Kryptonian|  5|
|Iron man|  1|           |    Mutant|  3|
|   Groot|  7|           |     Human|  1|
+--------+---+           +----------+---+

下面的展示图片中,其中相同的颜色表示的是能够Join匹配上的数据。下面的Join都是通过ID的方式来进行关联。

下面除了 Cross Join 之间,其它的都是通过如下说明

heroes.join(races, on='id', how='left').show()

说明在不同的 Join 的方式下不同效果。

Cross join 笛卡尔积

这个比较好理解,就是heroes表的数据和races表的数据进行Join,就是将heroes表的每一行数据都同races表的每一行数据进行联合。数据的数量级就是 m*n。不考虑Join的主键。

>>> heroes.crossJoin(races).show()
+--------+---+----------+---+  
|    name| id|      race| id|
+--------+---+----------+---+
|Deadpool|  3|Kryptonian|  5|
|Deadpool|  3|    Mutant|  3|
|Deadpool|  3|     Human|  1|
|Iron man|  1|Kryptonian|  5|
|Iron man|  1|    Mutant|  3|
|Iron man|  1|     Human|  1|
|   Groot|  7|Kryptonian|  5|
|   Groot|  7|    Mutant|  3|
|   Groot|  7|     Human|  1|
+--------+---+----------+---+

Inner join 内联合

只生成同时匹配表heroes和表races的记录集

Inner join

>>> heroes.join(races, on='id', how='inner').show()
+---+--------+------+ 
| id|    name|  race|
+---+--------+------+
|  1|Iron man| Human|
|  3|Deadpool|Mutant|
+---+--------+------+

Left join / Left outer join 左外联合

leftleft outer 是一个别名的关系。生成表heroes的所有记录,包括在表races里匹配的记录。如果没有匹配的,右边将是null。就是inner Join 的结果,再加上左边的表未匹配的所有的结果。

Left join

>>> heroes.join(races, on='id', how='left').show()
>>> heroes.join(races, on='id', how='leftouter').show()
+---+--------+------+
| id|    name|  race|
+---+--------+------+
|  7|   Groot|  null|
|  1|Iron man| Human|
|  3|Deadpool|Mutant|
+---+--------+------+

Right join / Right outer join 右外联合

同上左外联合类似。

Right join

>>> heroes.join(races, on='id', how='right').show()
>>> heroes.join(races, on='id, how='rightouter').show()
+---+--------+----------+ 
| id|    name|      race|
+---+--------+----------+
|  5|    null|Kryptonian|
|  1|Iron man|     Human|
|  3|Deadpool|    Mutant|
+---+--------+----------+

Full outer join 全外联合

outer和full 也是别名关系。生成表heroes和表races里的记录全集,包括两边都匹配的记录。如果有一边没有匹配的,缺失的这一边为null。

Full outer join

>>> heroes.join(races, on='id', how='outer').show()
>>> heroes.join(races, on='id', how='full').show()
+---+--------+----------+
| id|    name|      race|
+---+--------+----------+
|  7|   Groot|      null|
|  5|    null|Kryptonian|
|  1|Iron man|     Human|
|  3|Deadpool|    Mutant|
+---+--------+----------+

Left semi-join 左半连接

可以简单的看成是,inner join 之后,只保留能够Join上的左边表数据。

Left semi-join

>>> heroes.join(races, on='id', how='leftsemi').show()
+---+--------+
| id|    name|
+---+--------+
|  1|Iron man|
|  3|Deadpool|
+---+--------+

Left anti join

看成是Left semi-join 的取反操作,将左边中,没有匹配上的数据给取出。

Left anti join

>>> heroes.join(races, on='id', how='leftanti').show()
+---+-----+
| id| name|
+---+-----+
|  7|Groot|
+---+-----+

其它的补充

在Join的过程中,左边和右边都不能为None,可以是空数据的表但是需要带Schema,且Schema中有指定的关联主键(on)。

使用Pyspark 中创建空的DataFrame

  1. 创建空Schema的空DataFrame
  2. 创建带Schema的空DataFrame
def create_empty_df_without_schema():# Create an empty RDDemp_RDD = spark.sparkContext.emptyRDD()# Create empty schemacolumns = StructType([])return spark.createDataFrame(data=emp_RDD,schema=columns)def create_empty_df_with_schema():columns = StructType([StructField('name', StringType(), True),StructField('id', IntegerType(), True),])# emp_RDD = spark.sparkContext.emptyRDD()return spark.createDataFrame(data=[],schema=columns)

喜欢点个赞再走吧~

这篇关于一文让你记住Pyspark下DataFrame的7种的Join 效果的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1104888

相关文章

Java Thread中join方法使用举例详解

《JavaThread中join方法使用举例详解》JavaThread中join()方法主要是让调用改方法的thread完成run方法里面的东西后,在执行join()方法后面的代码,这篇文章主要介绍... 目录前言1.join()方法的定义和作用2.join()方法的三个重载版本3.join()方法的工作原

一文解密Python进行监控进程的黑科技

《一文解密Python进行监控进程的黑科技》在计算机系统管理和应用性能优化中,监控进程的CPU、内存和IO使用率是非常重要的任务,下面我们就来讲讲如何Python写一个简单使用的监控进程的工具吧... 目录准备工作监控CPU使用率监控内存使用率监控IO使用率小工具代码整合在计算机系统管理和应用性能优化中,监

一文详解如何使用Java获取PDF页面信息

《一文详解如何使用Java获取PDF页面信息》了解PDF页面属性是我们在处理文档、内容提取、打印设置或页面重组等任务时不可或缺的一环,下面我们就来看看如何使用Java语言获取这些信息吧... 目录引言一、安装和引入PDF处理库引入依赖二、获取 PDF 页数三、获取页面尺寸(宽高)四、获取页面旋转角度五、判断

一文详解SpringBoot中控制器的动态注册与卸载

《一文详解SpringBoot中控制器的动态注册与卸载》在项目开发中,通过动态注册和卸载控制器功能,可以根据业务场景和项目需要实现功能的动态增加、删除,提高系统的灵活性和可扩展性,下面我们就来看看Sp... 目录项目结构1. 创建 Spring Boot 启动类2. 创建一个测试控制器3. 创建动态控制器注

一文详解Git中分支本地和远程删除的方法

《一文详解Git中分支本地和远程删除的方法》在使用Git进行版本控制的过程中,我们会创建多个分支来进行不同功能的开发,这就容易涉及到如何正确地删除本地分支和远程分支,下面我们就来看看相关的实现方法吧... 目录技术背景实现步骤删除本地分支删除远程www.chinasem.cn分支同步删除信息到其他机器示例步骤

一文详解Java Stream的sorted自定义排序

《一文详解JavaStream的sorted自定义排序》Javastream中的sorted方法是用于对流中的元素进行排序的方法,它可以接受一个comparator参数,用于指定排序规则,sorte... 目录一、sorted 操作的基础原理二、自定义排序的实现方式1. Comparator 接口的 Lam

一文深入详解Python的secrets模块

《一文深入详解Python的secrets模块》在构建涉及用户身份认证、权限管理、加密通信等系统时,开发者最不能忽视的一个问题就是“安全性”,Python在3.6版本中引入了专门面向安全用途的secr... 目录引言一、背景与动机:为什么需要 secrets 模块?二、secrets 模块的核心功能1. 基

一文详解MySQL如何设置自动备份任务

《一文详解MySQL如何设置自动备份任务》设置自动备份任务可以确保你的数据库定期备份,防止数据丢失,下面我们就来详细介绍一下如何使用Bash脚本和Cron任务在Linux系统上设置MySQL数据库的自... 目录1. 编写备份脚本1.1 创建并编辑备份脚本1.2 给予脚本执行权限2. 设置 Cron 任务2

一文详解如何在idea中快速搭建一个Spring Boot项目

《一文详解如何在idea中快速搭建一个SpringBoot项目》IntelliJIDEA作为Java开发者的‌首选IDE‌,深度集成SpringBoot支持,可一键生成项目骨架、智能配置依赖,这篇文... 目录前言1、创建项目名称2、勾选需要的依赖3、在setting中检查maven4、编写数据源5、开启热

SQL中JOIN操作的条件使用总结与实践

《SQL中JOIN操作的条件使用总结与实践》在SQL查询中,JOIN操作是多表关联的核心工具,本文将从原理,场景和最佳实践三个方面总结JOIN条件的使用规则,希望可以帮助开发者精准控制查询逻辑... 目录一、ON与WHERE的本质区别二、场景化条件使用规则三、最佳实践建议1.优先使用ON条件2.WHERE用