【spark】示例:求Top值
我们有这样的两个文件
第一个数字为行号,后边为三列数据。我们来求第二列数据的Top(N)
(1)我们先读取数据,创建Rdd
(2)过滤数据,取第二列数据。
我们用filter()来过滤数据
line.trim().length是除去行末尾的空格然后计算长度,长度大于0,并且分能用逗号切分为4个子数据的数据为有效数据。
然后我们来切分取出第二列数据,即arr(2),arr(0)为行号
line.map(_.split(",")(2))
(3)数据类型转换并修改成键值对的形式
我们通过.map(x=>(x.toInt,""))把原来数据(string)修改成为(int,String)类型的键值对
为什么要这么做呢?因为我们要采用orderByKey()方法进行排序。
(4)排序取出键值对中的键
我们先调用orderByKey(false)方法对rdd中的每个键值对按照键值进行排序,false参数:是否正序
然后我们通过 x=>x._1 取排序后的键值对的键,最后通过take(N)方法即可实现取TOP(N)的功能
(5)将结果存入文件
通过saveAsTextFile(“file://”)方法将结果存入文件
完整代码
import org.apache.spark.{SparkConf, SparkContext} object TopN { //建立SparkContext val sparkConf = new SparkConf().setAppName("TopN") val sc = new SparkContext(sparkConf) //设置日志等级,只显示报错 sc.setLogLevel("ERROR") //读取数据,分区 val lines = sc.textFile("hdfs://localhost:9000/user/local/spark/data",2) var num = 0//排名初始化 var result = lines.filter(line => (line.trim.length > 0 && line.split(",").length > 4))//过滤数据 .map(_.split(",")(2)) //拆分文件取第二列数 .map(x =>(x.toInt,"")) //修改数据类型并转化为键值对的形式 .sortByKey(false)//排序 .map(x => x._1)//取键 .take(5)//取前五条数据 .foreach( x =>{ //显示数据 num = num + 1 //排名 println(num+"\t"+x) //显示 }) }
注意,我们在使用sortByKey方法前,数据是分了区的
我们使用了sortByKey方法将分区了的数据进行排序可能会出错,具体原因不是很清楚。
所以有时候我们需要在sortByKey()方法前加一个.partitionBy(new HashPartitioner(1))从新分成一个区来保证正确率。