想要使用scala生成来自上一行的值更改的唯一ID

时间:2016-04-02 03:58:06

标签: scala apache-spark

我想生成唯一ID作为给定列中上一行的值更改。我在Spark Scala中有数据框,并希望将Unique_ID列添加到现有数据框中。我不能将分区或groupBy上的行号用作多次相同的Product_ID,并且每次进入列时都需要Unique_ID。

Product_IDs Unique_ID
Prod_1           1
Prod_1           1
Prod_1           1
Prod_2           2
Prod_3           3
Prod_3           3
Prod_2           4
Prod_3           5
Prod_1           6
Prod_1           6
Prod_4           7

我需要使用Spark Scala这个数据框。

2 个答案:

答案 0 :(得分:1)

有一些方法可以添加一个我能想到的唯一ID的列。一种是使用zipWithUniqueId

val rows = df.rdd.zipWithUniqueId().map { 
    case (r: Row, id: Long) => Row.fromSeq(r.toSeq :+ id)
} 

val newDf = sqlContext.createDataFrame(rows, StructType(df.schema.fields :+ StructField("uniqueIdColumn", LongType, false)))

另一个是使用MonotonicallyIncreasingId函数:

import org.apache.spark.sql.functions.monotonicallyIncreasingId 
val newDf = df.withColumn("uniqueIdColumn", monotonicallyIncreasingId)

答案 1 :(得分:0)

这是一个不一定最有效的解决方案(我承认我找不到优化它的方法),而且有点长,但有效。

我假设输入由此案例类表示的记录组成:

case class Record(id: Int, productId: String)

id定义订单

我们将执行两项计算:

  1. 对于每条记录,找到不同 id
  2. 按该值分组(表示一组具有相同productId的连续记录,然后使用zipWithIndex创建我们感兴趣的唯一ID
  3. 我混合RDD操作(#2)和SQL(#1)主要是为了方便,我假设这两个操作都可以在任何API中完成(虽然我没有尝试):

    productId