我是Spark Scala的新手,我想使用两个数据帧或RDD来计算相似性变量。我没有在他们两个之间有一个共同的关键,我做了一个笛卡尔联合但加入的Df是巨大的。是否有可能从两个DF计算一个新变量而不加入它们?
例如:
df1.show
+----+------------+------+
| id1| food| level|
+----+------------+------+
|id11| pasta| first|
|id11| pizza|second|
|id11| ice cream| first|
|id12| spanish| first|
|id12| ice cream|second|
|id13| fruits| first|
+----+------------+------+
df2.show
+----+---------+
| id2| food|
+----+---------+
|id21| pizza|
|id21| fruits|
|id22| pasta|
|id22| pizza|
|id22|ice cream|
+----+---------+
对于来自df1的每个id1,我想通过id2从df2分组循环食物变量 我想得到这个输出:
+----+----+----------------+
| id1| id2|count_similarity|
+----+----+----------------+
|id11|id21| 1|id11 and id21 have only "pizza' in common
|id11|id22| 3|
|id12|id21| 0|
|id12|id22| 1|
|id13|id21| 1|
|id13|id22| 0|
+----+----+----------------+
是否可以使用RDD上的地图句子来计算? 谢谢
答案 0 :(得分:0)
您可以将两个数据帧都转换为rdd
,使用cartesian
方法计算每个ID对之间的相似度,然后重建数据框:
case class similarity(id1: String, id2: String, count_similarity: Int)
val rdd1 = df1.rdd.groupBy(_.getString(0)).mapValues(_.map(_.getString(1)).toList)
val rdd2 = df2.rdd.groupBy(_.getString(0)).mapValues(_.map(_.getString(1)).toList)
rdd1.cartesian(rdd2).map{
case (x, y) => similarity(x._1, y._1, x._2.intersect(y._2).size)
}.toDF.orderBy("id1").show
+----+----+----------------+
| id1| id2|count_similarity|
+----+----+----------------+
|id11|id22| 3|
|id11|id21| 1|
|id12|id21| 0|
|id12|id22| 1|
|id13|id21| 1|
|id13|id22| 0|
+----+----+----------------+
答案 1 :(得分:0)
这对你有用吗?
if