Spark 'join' DataFrame 与 List 并返回 String

Posted

技术标签:

【中文标题】Spark \'join\' DataFrame 与 List 并返回 String【英文标题】:Spark 'join' DataFrame with List and return StringSpark 'join' DataFrame 与 List 并返回 String 【发布时间】:2018-02-15 00:00:26 【问题描述】:

我有以下数据框:

DF1:
+------+---------+
|key1  |Value    |
+------+---------+
|[k, l]|      1  |
|[m, n]|      2  |
|[o]   |      3  |
+------+---------+

需要与另一个数据框“加入”

DF2:
+----+
|key2|
+----+
|k   |
|l   |
|m   |
|n   |
|o   |
+----+

让输出看起来像这样:

DF3:
+--------------------+---------+
|key3                |Value    |
+--------------------+---------+
|k:1 l:1 m:0 n:0 o:0 |      1  |
|k:0 l:0 m:1 n:1 o:0 |      2  |
|k:0 l:0 m:0 n:0 o:1 |      3  |
+--------------------+---------+

换句话说,输出数据帧应该有一列是 DF2 中所有行的字符串,并且每个元素后面应该跟一个 1 或 0,指示该元素是否存在于 DF1 的 key1 列的列表中.

我不知道该怎么做。我可以编写一个简单的 UDF 来完成我想要的吗?

【问题讨论】:

【参考方案1】:

这样的操作是可能的DF2所以你可以使用udf

import spark.implicits._
import org.apache.spark.sql.functions._

val df1 = Seq(
  (Seq("k", "l"), 1), (Seq("m", "n"), 2), (Seq("o"), 3)
).toDF("key1", "value")
val df2 = Seq("k", "l", "m", "n", "o").toDF("key2")

val keys = df2.as[String].collect.map((_, 0)).toMap

val toKeyMap = udf((xs: Seq[String]) => 
   xs.foldLeft(keys)((acc, x) => acc + (x -> 1)))


df1.select(toKeyMap($"key1").alias("key3"), $"value").show(false)

// +-------------------------------------------+-----+
// |key3                                       |value|
// +-------------------------------------------+-----+
// |Map(n -> 0, m -> 0, l -> 1, k -> 1, o -> 0)|1    |
// |Map(n -> 1, m -> 1, l -> 0, k -> 0, o -> 0)|2    |
// |Map(n -> 0, m -> 0, l -> 0, k -> 0, o -> 1)|3    |
// +-------------------------------------------+-----+

如果你只想要一个字符串:

val toKeyMapString = udf((xs: Seq[String]) => 
   xs.foldLeft(keys)((acc, x) => acc + (x -> 1))
     .map  case (k, v) => s"$k: $v" 
     .mkString(" ")
)


df1.select(toKeyMapString($"key1").alias("key3"), $"value").show(false)
// +------------------------+-----+
// |key3                    |value|
// +------------------------+-----+
// |n: 0 m: 0 l: 1 k: 1 o: 0|1    |
// |n: 1 m: 1 l: 0 k: 0 o: 0|2    |
// |n: 0 m: 0 l: 0 k: 0 o: 1|3    |
// +------------------------+-----+

【讨论】:

以上是关于Spark 'join' DataFrame 与 List 并返回 String的主要内容,如果未能解决你的问题,请参考以下文章

Spark SQL中Dataframe join操作含null值的列

全面解读 Spark SQL 之 Join 原理与实现

基于不同类型spark 1.6列的Spark join dataframe

Spark DataFrame join,需要两列,怎么做

Spark PairRDDs 和 DataFrames 是不是被索引?

Spark SQL 之 Join 实现