我希望基于两个键加入两个数据帧。如果没有匹配,我也想引入一个基于密钥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
但是对于k1和k2行,我想要val_type_b也被填充,因为基于关键1的部分匹配是可用的 - 对于k1,它可以是Y或Z而对于k2,它是W. 最有效的方法吗?
答案 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)