在Spark中反转对的键和值

时间:2018-03-12 15:05:50

标签: scala apache-spark

我想反转Key和值对客户ID和访问次数:

scala> val pair = input.map(line => line.split(" ") (2)).map(input => (input, 1)).reduceByKey(_+_).foreach(println)

结果:

(48784,3)
(47847,10)
(87673,8)
(67654,4)

我想颠倒这一对看起来像这样:

(3,48784)
(10,47847)
(8,87673)
(4,67654)

我在这个网站上研究了这个问题的类似答案,并尝试了以下方法。

  1. input.map{ pair => pair.swap}

  2. val PairReverse = pair.map(X => (x._2,x._1))

  3. val PairReverse = pair.map(X => ((1),(0))

  4. 我一直收到以下错误:

      

    "地图值不是本单元的成员"

4 个答案:

答案 0 :(得分:2)

pair属于Unit类型,因为它使用foreach,因为它不是功能操作(其结果是Unit)。如果您在.map(X => (x._2,x._1))调用之前添加foreach,请执行以下操作:

val pair = input.map(line => line.split(" ") (2)).map(input => (input, 1)).
    reduceByKey(_+_).map(X => (x._2,x._1)).foreach(println)

它应该有用。

答案 1 :(得分:1)

从以下行中删除.foreach(println),您应该没问题

val pair = input.map(line => line.split(" ") (2)).map(input => (input, 1)).reduceByKey(_+_).foreach(println)

由于foreach操作并返回unit()foreach定义看起来像

  
    

def foreach(f:T =>单位):单位

  

删除foreach()后,以下内容应该

val pair = input.map(line => line.split(" ") (2)).map(input => (input, 1)).reduceByKey(_+_)
val pairReverse = input.map(pair => pair.swap)
pairReverse.foreach(println)

val pair = input.map(line => line.split(" ") (2)).map(input => (input, 1)).reduceByKey(_+_)
val pairReverse = pair.map(x => (x._2,x._1))
pairReverse.foreach(println)

但是 您尝试过的最后一张地图 无效,即

val pair = input.map(line => line.split(" ") (2)).map(input => (input, 1)).reduceByKey(_+_)
val pairReverse = pair.map(X => ((1),(0)))
pairReverse.foreach(println)

因为它会为你拥有的每对产生(1,0)个元组

(1,0)
(1,0)
(1,0)
(1,0)

我希望答案很有帮助

答案 2 :(得分:1)

val pair = input.map(line => line.split(" ") (2)).map(input => (input, 1)).reduceByKey(_+_).foreach(println)

这会返回Unitforeach(println)会使该对成为单位。

val pair = input.map(line => line.split(" ") (2)).map(input => (input, 1)).reduceByKey(_+_)
// now print the pair rdd
pair.foreach(println)

//Now you can use it to swap using one of the following
pair.map(_.swap)
pair.map(x => (x._2,x._1))
pair.map(X => ((1),(0)))

因此,只需移除foreach(println)即可按预期工作

答案 3 :(得分:1)

以下是使用collect

交换每个元素的键值对的方法
 val map = Map(48784->3, 47847 -> 10, 87673 -> 8, 67654 -> 4)
 map: scala.collection.immutable.Map[Int,Int] = Map(48784 -> 3, 47847 -> 10, 87673 -> 8, 67654 -> 4)

scala> map.collect{
    case e => e._2 -> e._1
}
res0: scala.collection.immutable.Map[Int,Int] = Map(3 -> 48784, 10 -> 47847, 8 -> 87673, 4 -> 67654)