Scala 访问地图中的另一个rdd
以下是我的示例数据:Scala 访问地图中的另一个rdd,scala,apache-spark,Scala,Apache Spark,以下是我的示例数据: | rdd1 | | .... | | 10 | | 200 | | 350 | | 400 | | 1000 | | 1500 | | ..... | | rdd2 | | label | features | | .... | ....................... | | 0 | 1 10 30 100 200 450 600 | | 0 | 200 300 400
| rdd1 |
| .... |
| 10 |
| 200 |
| 350 |
| 400 |
| 1000 |
| 1500 |
| ..... |
| rdd2 |
| label | features |
| .... | ....................... |
| 0 | 1 10 30 100 200 450 600 |
| 0 | 200 300 400 |
| 1 | 200 350 450 |
| 1 | 400 600 700 |
| .... | ........................ |
我想计算以下内容:对于rdd1的每个元素,找出如何
它多次出现在rdd2中每个标签值的功能中。我
需要这样一个元组(#of times显示为标签0,#times
与标签1)一起出现,因此在上面的示例中,10与标签一起出现1次
用标签1标记0和0次,10次为(1,0)。200出现
2次使用标签0,1次使用标签1,因此对于
200
此外,我还想找出rdd1中每个元素的find out
有多少次它没有出现在rdd2中的特性中
标签值。我需要一个这样的元组(#的时间不会与
标签0,#次不与标签1一起出现)。所以在上面
例如,对于10我应该回去,它一次都没有出现
使用标签1(1,2)标记和两次
我计划按键使用聚合
val initialCount : collection.mutable.ListBuffer[Int] = ListBuffer(0, 0)
val addToCounts = (s: collection.mutable.ListBuffer[Int], label:Int) => if (label == 1) s(0) += 1 else s(1) += 1
val sumPartitionCounts = (p1: collection.mutable.ListBuffer[Int], p2: collection.mutable.ListBuffer[Int]) => ListBuffer((p1(0) + p2(0)),(p1(1) + p2(1)))
但是,我读到,不允许在另一个rdd的映射函数中访问rdd。任何关于我如何解决这个问题的想法都将非常好
val initialMap = scala.collection.mutable.Map.empty[String, Int]
val addToMap = (x: scala.collection.mutable.Map[String, Int], y: String) => {
if(x.contains(y))
x += ((y, x.get(y).get+1))
else
x += ((y, 1))
}
val mergeMaps = (x: scala.collection.mutable.Map[String, Int], y: scala.collection.mutable.Map[String, Int]) => {
x ++= y
}
val rdd2Aggregated: RDD[String, scala.collection.mutable.Map[String,Int] =
rdd2Mapped.aggregateByKey(initialMap)(addToMap, mergeMaps)
现在,要么广播rdd2Aggregated,要么将rdd1与rdd2Aggregated连接起来,并使用Map[label->frequency]获得所需的结果
对于问题的第二部分,以几乎类似的方式转换rdd2,但每个标签只具有不同的特性
val rdd2Mapped: RDD[String,String] = rdd2.flatMap(x => x._2.distinct.map(y => (y,x._1)))
像第一部分一样获取RDD[feature,Map[label,frequency]]。这将为您提供功能在rdd2中出现的次数。现在,从rdd2中获取每个标签的行数(rdd2中标签的简单字数)。您可以像以前一样使用这个新的RDD2聚合来连接rdd1,并进一步使用wordcount查找映射来连接结果rdd(如果wordcount查找映射足够小,也可以广播wordcount查找映射)。现在,对于每个功能,您都会得到标签和频率的映射。从查找映射的相应标签计数中减去每个标签的频率,以获得所需的答案
如果在给定的特征中,标签(标签,频率)中不存在标签,则认为该频率为0。请确保考虑这个边缘情况。
如果RDD足够小以适合于每个节点,那么您可以使用广播变量更新问题。谢谢你的想法。更新我的答案。这听起来很像一个hw q,所以我没有给你完整的代码,只是一个演练。mergeMaps函数应该更新为:val mergeMaps=(map1:collection.mutable.Map[Int,Int],map2:collection.mutable.Map[Int,Int])=>{map1++map2.Map{case(k,v)=>k->(v+map1.getOrElse(k,0))} val rdd2Mapped: RDD[String,String] = rdd2.flatMap(x => x._2.distinct.map(y => (y,x._1)))