访问Spark中的匿名地图作业的元组内部的元组

时间:2016-02-25 02:39:19

标签: scala apache-spark mapreduce word-count

  

这篇文章主要是关于如何从(String,String)RDD构建联合和边缘直方图。我发布了我最终在下面使用的代码作为答案。

我有一个RDD,其中包含一组(String,String)类型的元组,因为它们不是唯一的,我想看看每个字符串,字符串组合发生了多少次我这样使用countByValue

val PairCount = Pairs.countByValue().toSeq

它给我一个元组作为输出像这样((String,String),Long)其中long是(String,String)元组出现的次数

这些字符串可以以不同的组合重复,我基本上想在这个PairCount变量上运行字数,所以我尝试了这样的事情开始:

PairCount.map(x => (x._1._1, x._2))

但是这个输出的输出是String1-> 1,String2-> 1,String3-> 1等。

在这种情况下,如果键将成为内部元组的String值之一,那么如何从map作业输出键值对,并且该值将是来自outter元组的Long值?

更新: @vitalii几乎到了那里。答案让我得到了一个Seq [(String,Long)],但我真正需要的是把它变成一个地图,以便我可以在之后运行reduceByKey。我跑的时候

PairCount.flatMap{case((x,y),n) => Seq[x->n]}.toMap

每个唯一 x我得到x-> 1

例如,上面的代码行生成mom-> 1 dad-> 1,即使包含flatmap中的元组(妈妈,30)(爸爸,59)(妈妈,2)(爸爸,14)在这种情况下,我希望toMap提供mom-> 30,dad-> 59 mom-> 2 dad-> 14。但是,我是scala的新手,所以我可能会误解功能。

如何将Tuple2序列转换为地图以便我可以减少地图键?

2 个答案:

答案 0 :(得分:1)

如果我正确理解问题,你需要flatMap:

val pairCountRDD = pairs.countByValue() // RDD[((String, String), Int)]
val res : RDD[(String, Int)] = pairCountRDD.flatMap { case ((s1, s2), n) =>
   Seq(s1 -> n, s2 -> n)
}

更新:我并不安静了解你的最终目标是什么,但是这里有一些可能对你有帮助的例子,上面的btw代码不正确,我错过了countByValue返回map的事实,而不是RDD:

val pairs = sc.parallelize(
  List(
    "mom"-> "dad", "dad" -> "granny", "foo" -> "bar", "foo" -> "baz", "foo" -> "foo"
  )
)
// don't use countByValue, if pairs is large you will run out of memmory
val pairCountRDD = pairs.map(x => (x, 1)).reduceByKey(_ + _) 

val wordCount = pairs.flatMap { case (a,b) => Seq(a -> 1, b ->1)}.reduceByKey(_ + _)

wordCount.take(10)

// count in how many pairs each word occur, keys and values:
val wordPairCount = pairs.flatMap { case (a,b) => 
               if (a == b) {
                 Seq(a->1)
               } else {
                  Seq(a -> 1, b ->1)
               }
             }.reduceByKey(_ + _)
wordPairCount.take(10)

答案 1 :(得分:0)

获取(String,String)RDD的直方图我使用了这段代码。

val Hist_X  = histogram.map(x => (x._1-> 1.0)).reduceByKey(_+_).collect().toMap
val Hist_Y  = histogram.map(x => (x._2-> 1.0)).reduceByKey(_+_).collect().toMap
val Hist_XY = histogram.map(x => (x-> 1.0)).reduceByKey(_+_)

其中histogram是(String,String)RDD