使用带有scala的Spark RDD,每组的前n行

时间:2018-05-10 07:29:43

标签: scala apache-spark rdd

假设我有一个员工数据集,如下所示     的ID,姓名,性别,DEPT,SAL

    1,Sweta,F,10,1000
    2,Subham,M,11,2000
    3,Sawan,M,10,3000
    4,Sriya,F,11,4000
    5,Sravan,M,12,2000
    6,Suraj,M,11,1000
    7,Swetav,F,12,5000
    8,Sree,F,10,2000
    9,Sibani,F,12,3000
    10,Surya,M,10,2000

我有两个要求

1:查找每个部门的最高薪员工的所有详细信息      例如:我的输出应该像

  10   3,Sawan,M,10,3000
  11   4,Sriya,F,11,4000
  12   7,Swetav,F,12,5000

2:来自每个部门的前2名付费员工

注意: 允许仅使用带有Scala的Apache Spark RDD APi。 (严格来说不是数据帧或数据集Api)。所以任何人都可以帮忙。

1 个答案:

答案 0 :(得分:0)

更新

根据@Miguel的建议, 您可以使用topByKey表单包org.apache.spark.mllib.rdd.MLPairRDDFunctions.fromPairRDD

您需要先添加spark-mllib依赖项才能使用它

因此,如果你有一个rdd为department值创建一个键

val result = rdd.map(r  => (r._4, r))
  .topByKey(2)(Ordering[(Int)].on(x=>x._5))

这将为n中的n值提供 RDD [(Int,Array [(Int,String,String,Int,Int)])] 作为最高Arrays }。

要打印

result.foreach(x => println((x._1, x._2.mkString(","))))

输出:

(11,(4,Sriya,F,11,4000),(2,Subham,M,11,2000))
(12,(7,Swetav,F,12,5000),(9,Sibani,F,12,3000))
(10,(3,Sawan,M,10,3000),(8,Sree,F,10,2000))

第二个解决方案:

您也可以使用groupBy并找到最大值以获取该行,如下所示

// group rdd with department
val groupedRD = rdd.groupBy(x => x._4)

groupedRD.mapValues(r => r.maxBy(_._5))
  .foreach(println)

输出:

(11,(4,Sriya,F,11,4000))
(12,(7,Swetav,F,12,5000))
(10,(3,Sawan,M,10,3000))

现在转到n

groupedRD.mapValues(r => r.toList.sortWith(_._5 > _._5).take(2))
  .foreach(println)

输出:

(11,List((4,Sriya,F,11,4000), (2,Subham,M,11,2000)))
(12,List((7,Swetav,F,12,5000), (9,Sibani,F,12,3000)))
(10,List((3,Sawan,M,10,3000), (8,Sree,F,10,2000)))

希望这有帮助!