Pyspark下DataFrame的JOIN操作详解

1、数据预备

heroes_data = [
    ('Deadpool', 3), 
    ('Iron man', 1),
    ('Groot', 7)]
race_data = [
    ('Kryptonian', 5), 
    ('Mutant', 3), 
    ('Human', 1)]

heroes = spark.createDataFrame(heroes_data, ['name', 'id'])
+---------+---+
|   name  | id|           
+-------- +---+
|Deadpool |  3|           
|Iron man |  1|           
|   Groot |  7|           
+---------+---+           

races = spark.createDataFrame(race_data, ['race', 'id'])
+----------+---+
|     race | id|
+----------+---+
|Kryptonian|  5|
|    Mutant|  3|
|     Human|  1|
+----------+---+

2、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|
+----------+-----+-----------+----+

3、Inner join 内联合

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

在这里插入图片描述

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

4、Left join / Left outer join左外联合

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

在这里插入图片描述

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

5、Right join / Right outer join 右外联合

rightright outer 是一个别名的关系。生成表heroes的所有记录,包括在表races里匹配的记录。如果没有匹配的,左边将是null。就是inner 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|
+---+------------+-----------+ 

6、Full outer join 全外联合

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

在这里插入图片描述

>>> 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|
+---+-------------+------------+ 

7、Left semi-join 左半连接

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

在这里插入图片描述

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

8、Left anti join

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

在这里插入图片描述

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

9、其他补充

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

使用Pyspark 中创建空的DataFrame

  • 创建空Schema的空DataFrame
  • 创建带Schema的空DataFrame
def create_empty_df_without_schema():
    # Create an empty RDD
    emp_RDD = spark.sparkContext.emptyRDD()
    # Create empty schema
    columns = 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)
  • 8
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值