计数发生 - 阿帕奇星火斯卡拉
我本来的格式如下一组记录:计数发生 - 阿帕奇星火斯卡拉
(Title, Text)
哪里Title
是这本书的名字和Text
是其描述。
我已经统计Text
字段中的每个Word
的发生次数为Title
。它是按以下格式:
((Word, Title), WordCount)
现在,我要算独特的书Titles
具有Word
从Text
发生的数量。然后将其存储格式为:
((Word, Title), TitleCount)
哪里Count
是有这个Word
的Titles
数量。 我想这些信息存储在一个文件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.txt
和WordCount.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()
如果你想要的是计算间接火力(我不是很确定),然后按照下列步骤:
- 获取总文件的数量:
var numDocs = file.count()
- 反转拆分,使单词成为关键。
- 使用aggregateByKey()来获取与RDD [字,num_titles]
- 映射到最终的公式:
.map(x => (x._1, Log(numDocs/x._2.toDouble))
在那里,你会得到一个RDD [(文字,IDF):-)
我试过下面哪个工作正常。
- 我在
/home/cloudera/
上创建了一个文件。 (请将您的文件位置)。 - 斯卡拉>
val rpsteam=sc.textFile("file:///home/cloudera/RPS_Cricket_team.txt");
- 斯卡拉>
val rpscricket=rpsteam.flatMap(lines=>lines.split(" ")).filter(value=>value=="Rahane").map(word=>(word,1)).reduceByKey(_+_);
- 斯卡拉>
rpscricket.collect();
你的问题的一些清理将有助于如果我在错误的轨道是... –