Spark 2步加入

时间:2017-12-22 13:06:34

标签: apache-spark join dataframe

我希望基于两个键加入两个数据帧。如果没有匹配,我也想引入一个基于密钥1的匹配(密钥1可能有多个记录,可以选择任何一个,但只应引入一个记录)

像这样:

    val df1 = spark.sparkContext.parallelize( List( ("k0","k00","v0"),
    ("k1","k11","v1"),("k2","k22","v2") ) 
    ).toDF("key1","key2","val_type_a")

    val df2 = spark.sparkContext.parallelize( List( ("k0","k00","X"),
    ("k1","XX","Y"),("k1","YY","Z"),("k2","ZZ","W") ) 
    ).toDF("key1","key2","val_type_b")



    val df1_df2=df1.join(df2,Seq("key1","key2"),"left")
    df1.show
    df1_df2.show

Res

但是对于k1和k2行,我想要val_type_b也被填充,因为基于关键1的部分匹配是可用的 - 对于k1,它可以是Y或Z而对于k2,它是W. 最有效的方法吗?

1 个答案:

答案 0 :(得分:1)

您可以在2个连接中执行此操作:首先加入2列,然后加入剩余的1列。

一旦你完成拳头加入,你可以先在df2上使用groupBy +只保留一个值(第一个)

var df2_single = df2.groupby("key1).agg(first("val_type_b").alias("val_type_b"))

选择缺失值(第一次连接不起作用的地方):

var missing = df1_df2.filter(col("val_types_b").isNull).drop("val_types_2")

然后再次左转加入:

var df1_df2_missing = missing.join(df2_single, "key1", "left" )

并结合第一次加入和第二次加入的结果:

df1_df2 = df1_df2.filter(col("val_types_b").isNotNull).union(df1_df2_missing)