访问地图中的其他rdd

时间:2016-02-17 23:30:13

标签: 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              |   
|   1   | 200 350 450              |
|   1   | 400 600 700              |
|  .... | ........................ |
  

我想计算以下内容:对于rdd1的每个元素,请查明如何   很多时候,它出现在rdd2的每个标签值的功能中。一世   需要这样的元组(#of次出现标签0,#times   出现标签1)所以在上面的例子中,10出现1次   标签0和0次标签1为10,它将是(1,0)。 200出现   标签为0次,标签为1次,因此为(2,1)   200。

     

另外,我还想找出对于rdd1的每个元素找出来   它在rdd2中的每个特征中没有出现多少次   标签价值。我需要一个这样的元组(#of次不会出现   标签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的map函数中访问rdd。关于如何解决这个问题的任何想法都会很棒。

1 个答案:

答案 0 :(得分:0)

  1. 广播变量 - 如果您的rdd2足够小,请将其广播到每个节点,并将其用作rdd1.map中的查找或
  2. 加入 - 加入键值rdds
  3. 您必须重新构建rdd2才能获得广播var查找或加入所需的密钥。如果rdd2是 RDD [label,Array(feature)] ,我会尝试像这样得到 RDD [feature,label]

        val rdd2Mapped: RDD[String,String] = rdd2.flatMap(x => x._2.map(y => (y,x._1)))        
    

    然后使用aggregateByKey创建 RDD [feature,Map [label,frequency]]

        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或使用rdd2Aggregated加入rdd1并使用 Map [label->频率] 来获得所需的结果。

    对于问题的第二部分,以几乎相似的方式转换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中标签上的简单wordcount)。你像以前一样用这个新的rdd2Aggregated加入rdd1,并进一步加入带有wordcount查找映射的结果rdd(或者如果足够小则广播wordcount查找映射)。现在,对于每个功能,您都会获得标签和频率的映射。从查找映射中的相应标签计数中减去每个标签的频率,以获得所需的答案。

    如果给定特征的Map [label,frequency]中不存在标签,请将该频率视为0.请务必考虑此边缘情况。