如何根据spark scala

时间:2015-10-05 11:02:15

标签: scala apache-spark

我已经完成了在apache spark中使用Mllib ALS构建推荐,输出

user | product | rating
    1 | 20 | 0.002
    1 | 30 | 0.001
    1 | 10 | 0.003
    2 | 20 | 0.002
    2 | 30 | 0.001
    2 | 10 | 0.003

但我需要根据评级排序来改变数据结构,例如:

user | product | rating | number_rangking
    1 | 10 | 0.003 | 1
    1 | 20 | 0.002 | 2 
    1 | 30 | 0.001 | 3
    2 | 10 | 0.002 | 1
    2 | 20 | 0.001 | 2
    2 | 30 | 0.003 | 3

我该怎么做?也许任何人都可以给我一个线索......

THX

1 个答案:

答案 0 :(得分:1)

您需要的只是一个窗口功能,具体取决于您选择的详细信息rankrowNumber

import org.apache.spark.sql.expressions.Window
import org.apache.spark.sql.functions.rank

val w = Window.partitionBy($"user").orderBy($"rating".desc)

df.select($"*", rank.over(w).alias("number_rangking")).show
// +----+-------+------+---------------+
// |user|product|rating|number_rangking|
// +----+-------+------+---------------+
// |   1|     10| 0.003|              1|
// |   1|     20| 0.002|              2|
// |   1|     30| 0.001|              3|
// |   2|     10| 0.003|              1|
// |   2|     20| 0.002|              2|
// |   2|     30| 0.001|              3|
// +----+-------+------+---------------+

使用普通RDD,您可groupByKey,在本地处理flatMap

rdd
  // Convert to PairRDD
  .map{case (user, product, rating) => (user, (product, rating))}
  .groupByKey 
  .flatMap{case (user, vals) => vals.toArray
    .sortBy(-_._2) // Sort by rating
    .zipWithIndex // Add index
    // Yield final values
    .map{case ((product, rating), idx) => (user, product, rating, idx + 1)}}