我最初有以下格式的一组记录:
(Title, Text)
其中Title
是图书的名称,Text
是其描述。
我已计算Word
字段中Text
字段中Title
的每个((Word, Title), WordCount)
的出现次数。它采用以下格式:
Titles
现在,我想计算Word
中出现Text
的不同图书((Word, Title), TitleCount)
的数量。然后将其存储为以下格式:
Count
Titles
是具有此Word
的{{1}}的数量。
我想将其存储在文件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(",")))))))
^
更新
我也尝试了这个:
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
可能包含","
,但这将是一个简单的正则表达式修复。
为了获得每个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)
这是一个实际的乘法,而不是出于表示目的。
有人可以帮我解决这个问题吗? 谢谢!
答案 0 :(得分:2)
我在下面尝试过,效果很好。
/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();
答案 1 :(得分:0)
我无法猜测yourRdd
,file
等的数据类型是什么,所以我无法真正理解您的原始示例。
一般来说,要弄清楚这些类型的问题,请拆分成多个语句并在变量上声明数据类型,特别是在lambdas的左侧(x: Int =&gt; ...) 。然后编译器或IDE会告诉你你在哪里误入歧途。如果您使用的是IDE,它可能有一个键盘快捷键,用于向变量添加类型声明。学习它。这是Intellij的alt-enter。
在这种情况下,即使我无法理解整个代码,但错误消息告诉您File.filter
正在返回字符串元组的集合,而不是字符串,所以_.split
无效。
答案 2 :(得分:0)
嗯,错误真的告诉了一切。定义闭包时:
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)
,实际上没有spit方法。例如,您可以使用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()
如果你想要的是计算IDF(我不完全确定),请按照以下步骤操作:
var numDocs = file.count()
.map(x => (x._1, Log(numDocs / x._2.toDouble))
在那里,你得到一个RDD [(Word,IDF)]: - )