使用Spark和Scala计算字数

时间:2015-06-09 13:59:09

标签: scala apache-spark

我必须在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!")
    }
}

5 个答案:

答案 0 :(得分:5)

我建议您在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内部的更多信息,请参阅此link

答案 1 :(得分:2)

问题是您在分布式集上使用可变变量。这在正常情况下很难控制,特别是在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组合在一起的组合器。

答案 2 :(得分:0)

我认为迭代: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!")

答案 3 :(得分:0)

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

答案 4 :(得分:-1)

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

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