如何在Scala中使用唯一标识符爆炸Spark数据框数组字段?

时间:2018-09-21 18:07:15

标签: scala apache-spark apache-spark-sql

我有一个数据框,如下所示:

+-----------+
|        f1 |
+-----------+
|[a,b,c]    |
|[e,f,g]    |
|[h,i]      |
+-----------+

我想将其与重复的唯一数字字段一起爆炸成行,如下所示:

+-----------+--------+
|        f1 |     uid|
+-----------+--------+
|a          |       1|
|b          |       1|
|c          |       1|
|e          |       2|
|f          |       2|
|g          |       2|
|h          |       3|
|i          |       3|
+-----------+--------+

我可以按照此处的说明直接执行爆炸-Spark: Explode a dataframe array of structs and append id

但是我不确定如何将uid字段添加到新的数据框中,以便每个分解的数组字段将具有相同的uid而其他元素具有不同的uid值。

1 个答案:

答案 0 :(得分:3)

正确的方法是使用monotonically_increasing_id

val df = Seq(Seq("a", "b", "c"), Seq("e", "f", "g"), Seq("h", "i")).toDF("f1")

df
  .withColumn("uid", monotonically_increasing_id)
  .withColumn("f1", explode($"f1"))
  .show
// +---+---+                                                                       
// | f1|uid|
// +---+---+
// |  a|  0|
// |  b|  0|
// |  c|  0|
// |  e|  1|
// |  f|  1|
// |  g|  1|
// |  h|  2|
// |  i|  2|
// +---+---+

该数字不必像示例中那样是连续的,但将唯一地标识来源。

请勿使用rank().over(Window.orderBy("f1"))。它本质上是顺序的,不能伸缩,因此应避免使用,除非是本地Datasets(即从true返回isLocal的地方)。