[英]Join 2 DataFrame based on lookup within a Column of collections - Spark,Scala
我有以下2個數據框,
val x = Seq((Seq(4,5),"XXX"),(Seq(7),"XYX")).toDF("X","NAME")
val y = Seq((5)).toDF("Y")
我想通過從y
查找值並在x.select("X")
搜索Seq / Array來連接兩個數據幀,然后將完整的Row與y一起連接
我如何才能做到這是Spark?
干杯!
Spark 2.4.3可以使用高階函數spark
scala> val x = Seq((Seq(4,5),"XXX"),(Seq(7),"XYX")).toDF("X","NAME")
scala> val y = Seq((5)).toDF("Y")
scala> x.join(y,expr("array_contains(X, y)"),"left").show
+------+----+----+
| X|NAME| Y|
+------+----+----+
|[4, 5]| XXX| 5|
| [7]| XYX|null|
+------+----+----+
請確認這是您想要實現的目標?
您可以將UDF用於聯接,適用於所有spark版本:
val array_contains = udf((arr:Seq[Int],element:Int) => arr.contains(element))
x
.join(y, array_contains($"X",$"Y"),"left")
.show()
您可以使用的另一種方法是使用新的臨時列將數組explode
成行。 如果運行以下代碼:
x.withColumn("temp", explode('X)).show()
它會顯示:
+------+----+----+
| X|NAME|temp|
+------+----+----+
|[4, 5]| XXX| 4|
|[4, 5]| XXX| 5|
| [7]| XYX| 7|
+------+----+----+
如您所見,您現在可以使用temp
和Y
列進行temp
(然后刪除temp
):
x.withColumn("temp", explode('X))
.join(y, 'temp === 'Y)
.drop('temp)
如果X
包含重復項,則可能會因創建重復行而失敗。 在這種情況下,您必須另外調用distinct
:
x.withColumn("temp", explode('X))
.distinct()
.join(y, 'temp === 'Y, "left")
.drop('temp)
由於這種方法使用的是Spark本機方法,因此比使用UDF的方法要快一點,但可以說它不夠優雅。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.