繁体   English   中英

使用Spark和Scala的字数统计

[英]Word count using Spark and Scala

我必须在Scala中编写一个程序,使用spark计算一个单词在文本中出现的次数,但是使用RDD时,变量计数始终在末尾显示0。 你能帮我吗? 这是我的代码

import scala.io.Source
import org.apache.spark.SparkContext
import org.apache.spark.SparkContext._
import org.apache.spark.SparkConf

object wordcount {
    def main(args: Array[String]) {
      // set spark context
      val conf = new SparkConf().setAppName("wordcount").setMaster("local[*]")
      val sc = new SparkContext(conf)

      val distFile = sc.textFile("bible.txt")

      print("Enter word to loook for in the HOLY BILE: ")
      val word = Console.readLine
      var count = 0;
      println("You entered " + word)

      for (bib <- distFile.flatMap(_.split(" "))) {

        if (word==bib) {
            count += 1

        }

      }  
      println(word + " occours " + count + " times in the HOLY BIBLE!")
    }
}

我建议您在RDD中使用可用的转换,而不是使用自己的程序(尽管它没有害处)以获得所需的结果,例如,可以使用以下代码来检索字数。

val word = Console.readLine
println("You entered " + word)
val input = sc.textFile("bible.txt")
val splitedLines = input.flatMap(line => line.split(" "))
                    .filter(x => x.equals(word))

System.out.println(splitedLines.count())

请参考此链接以获取有关Spark内部信息的更多信息。

问题是您正在分布式集合上使用可变变量。 在正常情况下,这很难控制,尤其是在Spark中,该变量分别复制到每个工作线程。 因此,它们最终具有自己的count变量版本,而原始变量实际上从未更新。 您将需要使用一个accumulator ,这只能保证动作。 综上所述,您无需变量或累加器即可完成此操作:

val splitData = distFile.flatMap(_.split(" "))
val finalCount = splitData.aggregate(0)(
  (accum, word) => if(word == bib) accum + 1 else accum,
  _ + _)

这是在做的事情,首先为计数加0。然后,第一个操作是将在每个分区上运行的操作。 accum是累计计数和word是当前词比较。 第二个操作只是简单的组合器,用于将所有分区的count相加。

我认为迭代: bib <- distFile.flatMap(_.split(" "))将不起作用,因为您的数据位于RDD中,请尝试执行以下收集:

for (bib<-distFile.flatMap(_.split(" ")).collect)

(它可以在您的数据不多的情况下起作用,您可以对其进行收集)

否则,如果您的数据集巨大,则可以执行以下操作:

val distFile = sc.textFile("bible.txt")
val word = Console.readLine
val count = distFile.flatMap(_.split(" ")).filter(l=>l==word).count
println(word + " occours " + count + " times in the HOLY BIBLE!")
val textFile = sc.textFile("demoscala.txt")
val counts = textFile.flatMap(line => line.split(" ")).map(word => (word, 1)).reduceByKey(_ + _)
counts.saveAsTextFile("WordCountSpark")  

如果有人对(_)感到困惑。

http://www.codecommit.com/blog/scala/quick-explanation-of-scalas-syntax

val text=sc.textfile("filename.txt")

val counts=text.flatmap(line=>line.split("")).map(word=>(word,1)).reduceByKey(_+_) counts.collect

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM