8、Spark DataFrame理解和使用之两个DataFrame的关联操作

Spark之两个DataFrame的操作

1、inner

2、outer

3、left_outer

4、right_outer

5、left_semi

6、left_anti

7、union

注:这里只采用DF的操作语法,至于将DF创建成视图使用SQL的语法这里就不介绍了。


一、创建DF备用

(1)手工输入几条测试数据,快速构造一个测试DataFrame备用

#python
#手动输入几条数据,构造一个简单的测试DataFrame
df1 = spark.createDataFrame([
                (500, "Vice President","hello"),
                (250, "PMC Member","hi"),
                (100, "Contributor","salut")]).toDF("col1", "col2","col3")

(2)从文件中读取(自定义schema, 自动推断schema/意味着header = true)

#in python
hdfs_csv_file = "hdfs://path/to/file.csv"
from pyspark.sql.types import StructField, StructType, StringType, IntegerType
myManualSchema = StructType([
			StructField("col1", IntegerType(), True),
			StructField("col2", StringType(), True),
			StructField("col3", StringType(), True)
			])
df2 = spark.read.format("csv").schema(myManualSchema).load(hdfs_csv_file)

(3)创建空的(自定义schema, 复制已有schema)

#当新建的DataFrame结构与已知的DataFrame结构一样的时候,可以直接调用另一个DF.schema
df0 = spark.createDataFrame(spark.sparkContext.emptyRDD(), df2.schema)


二、两个DF的关联( 使用DF语言的操作)inner、outer、left_outer、right_outer、left_semi、left_anti、union

1、内关联 inner

#1、df1和df2做内关联,关联列为一个:"col1"。两个DF都有要关联的列,且列名相同
df3 = df1.join(df2,["col1"],"inner")
df3 = df1.join(df2,["col1"])  #inner join 是默认的join方式,所以可以省略这个参数

#2、df1和df2做内关联,关联列为一个:"col1"。两个DF都有要关联的列,但列名不同
df3 = df1.join(df2,df1["col1"] == df2["id"],"inner")

#3、df1和df2做内关联,关联列为多个:"col1","col2","col3"。两个DF都有要关联的列,且列名相同
df3 = df1.join(df2,["col1","col2","col3"],"inner")

#4、df1和df2做内关联,关联列为多个:"col1","col2","col3"。两个DF都有要关联的列,但列名不同
df3 = df1.join(df2,???,"inner")

2、外关联(即全关联) outer

#1、df1和df2做外关联,关联列为一个:"col1"。两个DF都有要关联的列,且列名相同
df3 = df1.join(df2,["col1"],"outer")

#2、df1和df2做外关联,关联列为多个:"col1","col2","col3"。两个DF都有要关联的列,且列名相同
df3 = df1.join(df2,["col1","col2","col3"],"outer")

3、左关联 left_outer

#1、df1和df2做左外关联,关联列为一个:"col1"。两个DF都有要关联的列,且列名相同
df3 = df1.join(df2,["col1"],"left_outer")

#2、df1和df2做左外关联,关联列为多个:"col1","col2","col3"。两个DF都有要关联的列,且列名相同
df3 = df1.join(df2,["col1","col2","col3"],"left_outer")

4、右关联 right_outer

#1、df1和df2做右外关联,关联列为一个:"col1"。两个DF都有要关联的列,且列名相同
df3 = df1.join(df2,["col1"],"right_outer")

#2、df1和df2做右外关联,关联列为多个:"col1","col2","col3"。两个DF都有要关联的列,且列名相同
df3 = df1.join(df2,["col1","col2","col3"],"right_outer")

5、左半关联 left_semi

左半关联相当于SQL中的IN 函数,快速判断左边列是否在右边表中,在就保留行,不在就不保留这行数据。

或者像其他解释说的,右边的表相当于filter过滤条件。

#in python
#1、df1和df2做左半关联,关联列为一个:"col1"。两个DF都有要关联的列,且列名相同
df3 = df1.join(df2,["col1"],"left_semi")

6、左反关联 left_anti

左反关联相当于SQL中的NOT IN 函数,快速判断左边列是否在右边表中,在就不保留行,不在就保留这行数据。 这是跟left_semi 完全相反的函数。

#in python
#1、df1和df2做左反关联,关联列为一个:"col1"。两个DF都有要关联的列,且列名相同
df3 = df1.join(df2,["col1"],"left_anti")

7、两个DF 做union合并

两个DataFrame做合并的时候要确保它们具有相同的schema和列数,否则会失败。

#in python
df3 = df1.union(df2)

问题:如果df1 和df2 都有三列相同列名的列:col1 、col2 、col3, 而我们关联的时候仅使用col1做为两个DF的关联列,那么生成的DF会有几列col2、col3? 如果列名重复了,又该怎么处理呢?

关于DataFrame的复杂结构的关联操作,请参考 博文: 

 

三、将关联操作后的DF排序、去重后写出

1、DF排序 sort 、orderBy

#in python 
#1、 orderBy排序, 按照列"col2","col1" 来排序
df2.orderBy("col2","col1")

#2、sort排序
df2.sort("col2","col1")

2、DF去重 distinct

df.select("col1", "col2").distinct()

3、DF写出到HDFS的CSV文件/TXT文件中

df2.write.format("csv").mode("overwrite").option("sep",",").option("header",True).save(hdfs_result)

4、DF写出到ES或CK或SQL等

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值