计数发生 - 阿帕奇星火斯卡拉

问题描述:

我本来的格式如下一组记录:计数发生 - 阿帕奇星火斯卡拉

(Title, Text) 

哪里Title是这本书的名字和Text是其描述。

我已经统计Text字段中的每个Word的发生次数为Title。它是按以下格式:

((Word, Title), WordCount) 

现在,我要算独特的书Titles具有WordText发生的数量。然后将其存储格式为:

((Word, Title), TitleCount) 

哪里Count是有这个WordTitles数量。 我想这些信息存储在一个文件TitleCount.txt

要计算TitleCount

val idfRdd = yourRdd.flatMap(title => (title, scala.math.log(N/(file.filter(_.split("\t")(1).contains(title.split(","))))))) 

N = fixed number (20)

但这个代码无法给出错误:

scala> val idfRdd = yourRdd.flatMap(title => (title, scala.math.log(N/(file.filter(_.split("\t")(1).contains(title.split(","))))))) 
<console>:31: error: value split is not a member of (String, String) 
     val idfRdd = yourRdd.flatMap(title => (title, scala.math.log(N/(file.filter(_.split("\t")(1).contains(title.split(","))))))) 
                               ^

UPDATE

我尝试这样做,以及:

val r = splitRdd.flatMap(arr => { 
    val title = arr(0) 
    val text = arr(1) 
    val words = text.split(" ") 
    words.map(word => ((word, title), scala.math.log(N/(file.filter(_.split("\t")(1).contains(word))).count))) }) 

上面的代码编译,但在运行时出现故障。

Title可能包含","但这将是一个简单的正则表达式修复。乘以计数字段

val file = sc.textFile("s3n://bucket/test.txt") // RDD[ String ] 
val splitRdd = file.map(line => line.split("\t")) // RDD[ Array[ String ] 

val yourRdd = splitRdd.flatMap(arr => { 
     val title = arr(0) 
     val text = arr(1) 
     val words = text.split(" ") 
     words.map(word => (word, title)) 
    }) 
    // RDD[ (String, String) ] 

val countRdd = yourRdd.map(title => (title, 1)).reduceByKey(_ + _) 
countRdd.saveAsTextFile("s3n://bucket/wordcount.txt") 

进一步阅读

我想然后合并这两个文件TitleCount.txtWordCount.txt: 为了获得个人字数每一个标题,我写了下面的代码两份文件。 这给我们:

FinalCount.txt 

((Word, Title), WordCount * TitleCount) 

这是一个实际的乘法,而不是为代表的目的。

有人可以帮我解决这个问题吗? 谢谢!

我不能猜测数据类型是yourRdd,file等,所以我不能真正理解你的原始示例。

一般来说,要弄清楚这些类型的问题,可以分解成多个语句并在变量上声明数据类型,特别是在lambdas左侧(x:Int => ...)。然后编译器或IDE会告诉你你误入歧途的地方。如果你使用的是IDE,它可能有一个键盘快捷键,用于向变量添加一个类型声明。学习它。这对Intellij来说是可以接受的。

在这种情况下,即使我无法理解的代码作为一个整体,该错误信息是告诉你,File.filter将返回字符串元组,而不是字符串的集合,所以_.split不上它的工作。

嗯,错误真的告诉了一切。当你定义关闭:

val idfRdd = yourRdd.flatMap(title => (title, scala.math.log(N/(file.filter(_.split("\t")(1).contains(title.split(","))))))) 
<console>:31: error: value split is not a member of (String, String) 
     val idfRdd = yourRdd.flatMap(title => (title, scala.math.log(N/(file.filter(_.split("\t")(1).contains(title.split(","))))))) 

特别title => ...,你匹配yourRdd RDD里面的类型。如果这是你的初始输入,那么这个类型是一个元组(String, String),它确实没有吐出方法。例如,您可以使用title._2

现在,根据文本的数量和大小,您可能需要利用spark来完成内部计数。举例来说,通过做

// Get an RDD[title, word], then a hashmap with all counts 
val split = file.flatMap(x => x._2.split(",").map(y => (x._1, y))) 
val counts = split.countByKey() 

如果你想要的是计算间接火力(我不是很确定),然后按照下列步骤:

  1. 获取总文件的数量:var numDocs = file.count()
  2. 反转拆分,使单词成为关键。
  3. 使用aggregateByKey()来获取与RDD [字,num_titles]
  4. 映射到最终的公式:.map(x => (x._1, Log(numDocs/x._2.toDouble))

在那里,你会得到一个RDD [(文字,IDF):-)

+0

你的问题的一些清理将有助于如果我在错误的轨道是... –

我试过下面哪个工作正常。

  1. 我在/home/cloudera/上创建了一个文件。 (请将您的文件位置)。
  2. 斯卡拉>val rpsteam=sc.textFile("file:///home/cloudera/RPS_Cricket_team.txt");
  3. 斯卡拉>val rpscricket=rpsteam.flatMap(lines=>lines.split(" ")).filter(value=>value=="Rahane").map(word=>(word,1)).reduceByKey(_+_);
  4. 斯卡拉>rpscricket.collect();