Spark简单项目之词频统计

import org.apache.spark.{SparkContext, SparkConf}
//这样引入是为引入reduceByKey
import org.apache.spark.SparkContext._

/**
  在给定的莎士比亚文集上(多个文件),根据规定的停词表,统计出现频度最高的 100 个单词。
  实现后的程序应该满足下列要求:输入指定文件夹下的所有莎翁文集文件,
  停词表中出现的单词不计算词频,输出结果为出现频次最高的100个单词。
 * Created by sucre on 2016/3/6.
 */
object WordCount1 {
  def main(args: Array[String]) {
    val appName = "WordCount"
    //如果是在spark-shell执行,那么conf和sc是不用创建的;但是如何要用spark-submit执行scala
    //的jar,那么conf和sc是需要的
    val conf = new SparkConf().setMaster("local").setAppName(appName)
    val sc = new SparkContext(conf)
    val inputFiles = "/home/sucre/wordcount/shakespear/*"
    val stopWordFile = "/home/sucre/wordcount/stopword.txt"
    val inputRDD = sc.textFile(inputFiles)
    val stopRDD = sc.textFile(stopWordFile)
    /**
     * 输入的文件内容里除了英文单词之外,还有下面的特殊符号,这些符号不应该计算到统计中:
       制表符,反斜线,句号,逗号,竖线,中括号,问号,破折号,叹号,分号,其他英文符号
       我们需要使用空格替换这些标点符号,同时将替换后的行拆分成单词。
     */
    val targetList:Array[String] = Array[String]("""\t\().,?[]!;|""")
    def replaceAndSplit(s:String):Array[String]={
      for(c<-targetList){
        s.replace(c," ")
      }
      s.split("\\s+")
    }
    val inputRDDv1 = inputRDD.flatMap(replaceAndSplit)
    //将停词表里的空行去除并获得列表
    val stopList = stopRDD.map(x=>x.trim()).collect()
    //输入文件RDD中如果出现停词表中的单词,则去除该单词
    val inputRDDv2 = inputRDDv1.filter(x=>stopList contains x)
    //将每个单词Map到一个元组:(word,1)
    val inputRDDv3 = inputRDDv2.map(x=>(x,1))
    //通过reduce操作,根据上一步骤输出的元组中的单词以x为key,
    // 将后面第二个元素的数字进行相加
    val inputRDDv4 = inputRDDv3.reduceByKey(_ + _)
    inputRDDv4.saveAsTextFile("/tmp/v4output")
    //将词频统计的结果进行一次元组位置的交换,将频次放到第一个元素,而单词放到第二个元素
    val inputRDDv5 = inputRDDv4.map(x=>x.swap)
    //交换后进行按频次排序,参数ascending=False表示降序排列
    val inputRDDv6 = inputRDDv5.sortByKey(false)
    //排序后我们需要提取所有的单词,去掉元组中的频次信息,只需要单词列表
    val inputRDDv7 = inputRDDv6.map(x=>x.swap).keys
    //提取前100的元素
    val top100 = inputRDDv7.take(100)
    val outputFile="/tmp/result"
    val result =sc.parallelize(top100)
    result.saveAsTextFile(outputFile)
  }
}

将以上代码编译成jar文件,然后用spark-submit去提交看看,代码中的inputFiles和outFiles可以写成两个参数,这样就可以做为通用的了。

你可能感兴趣的:(scala,spark,RDD)