加入RDD以获得交集的补充

时间:2017-03-18 04:22:44

标签: scala join apache-spark rdd

我有两个RDD: 第一个(用户ID,Mov ID,评级,时间戳)

data_wo_header: RDD[String]
scala> data_wo_header.take(5).foreach(println)
1,2,3.5,1112486027
1,29,3.5,1112484676
1,32,3.5,1112484819
1,47,3.5,1112484727
1,50,3.5,1112484580

和RDD2(用户ID,Mov ID)

data_test_wo_header: RDD[String]
scala> data_test_wo_header.take(5).foreach(println)
1,2
1,367
1,1009
1,1525
1,1750

我需要加入两个RDD,以便加入将删除RDD1中常用的条目(UserID,Mov ID)。 有人可以指导两个RDD的scala-spark连接。 此外,我还需要一个连接,其中从RDD1派生的新RDD只有公共项目。

2 个答案:

答案 0 :(得分:0)

首先将您的RDD转换为DataFrame,因为DataFrame具有常见的SQL,如API,例如join,select等。

要将RDD转换为DataFrame,您需要RDD [Row]而不是RDD [String]。

Import sqlContext.implicits._

case class cs1(UserID: Int, MovID: Int, Rating: String, Timestamp: String)

case class cs2(UserID: Int, MovID: Int)

val df1 = data_wo_header.map(row => {
   val splits = row.split(",")

   cs1(splits(0).toInt, splits(1).toInt, splits(2),splits(3))
}).toDF("UserID", "MovID", "Rating", "Timestamp")

 val df2 = data_test_wo_header.map(row => {
   val splits = row.split(",")

   cs2(splits(0).toInt, splits(1).toInt)
}).toDF("UserID", "MovID")

现在,向df2添加一个新列,

val df2Prime = df2.withColumn("isPresent", lit(1))

然后用df1连接df2Prime并过滤掉isPresent为1的行,并且你有相交的结果。另外,删除临时isPresent标志。

val temp = df1.join(df2Prime, usingColumns = Seq("UserID", "MovID"), "left")

temp.filter(temp("isPresent") =!= "1").drop("isPresent")

答案 1 :(得分:0)

一种超级简单的方法是使用按键减法。以下是为我工作:

val data_wo_header=dropheader(data).map(_.split(",")).map(x=>((x(0),x(1)),(x(2),x(3))))
val data_test_wo_header=dropheader(data_test).map(_.split(",")).map(x=>((x(0),x(1)),1))
val ratings_train=data_wo_header.subtractByKey(data_test_wo_header)
val ratings_test=data_wo_header.subtractByKey(ratings_train)