晕
我已经完成了在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
答案 0 :(得分:1)
您需要的只是一个窗口功能,具体取决于您选择的详细信息rank
或rowNumber
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)}}