2015-04-23 106 views
0

我本來的格式如下一組記錄:計數發生 - 阿帕奇星火斯卡拉

(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) 

這是一個實際的乘法,而不是爲代表的目的。

有人可以幫我解決這個問題嗎? 謝謝!

回答

0

我不能猜測數據類型是yourRdd,file等,所以我不能真正理解你的原始示例。

一般來說,要弄清楚這些類型的問題,可以分解成多個語句並在變量上聲明數據類型,特別是在lambdas左側(x:Int => ...)。然後編譯器或IDE會告訴你你誤入歧途的地方。如果你使用的是IDE,它可能有一個鍵盤快捷鍵,用於向變量添加一個類型聲明。學習它。這對Intellij來說是可以接受的。

在這種情況下,即使我無法理解的代碼作爲一個整體,該錯誤信息是告訴你,File.filter將返回字符串元組,而不是字符串的集合,所以_.split不上它的工作。

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),它確實沒有吐出方法。例如,您可以使用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

我試過下面哪個工作正常。

  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();