Java、Scala、Python ☞ 本地WordCount詞頻統計對比
需求:模擬MapReduce,對磁碟檔案(N個)裡面的單詞進行詞頻統計(統計每個單詞在檔案中出現的次數)
區別:計算採用本地模式(單執行緒),只是模擬Map和Reduce的聯合過程,並不單獨分離出兩個任務(方法)
目的:通過不同語言實現詞頻統計功能,並對比各自的風格
一、資料樣例(Samples)
百度網盤:wordcount.rar
主要是為了測試,所以資料儘量怎麼簡單怎麼來,也可以自定義樣例資料
二、思路
三、程式設計實現
(1) Java demo實現
package com.appleyk.java;
import sun.applet.Main;
import java.io.*;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* @Description
* @Author Appleyk
* @Blob https://blog.csdn.net/appleyk
* @Date Created on 上午 8:44 2018-9-6
*/
public class JWordCount {
// main方法快捷鍵 : psvm
public static void main(String[] args) throws Exception{
System.out.println("================Java=============");
String path = "F:\\wordcount";
File dirFile = new File(path);
// file陣列
File[] files = dirFile.listFiles();
for (File f : files) {
System.out.println(f);
}
// file陣列轉List
List<File> fileList = Arrays.asList(files);
Map<String,Integer> wordMap = new HashMap<>();
fileList.forEach(file->{
try{
BufferedReader bReader = new BufferedReader(new FileReader(file));
// 迴圈讀取行
String line = "";
while((line=bReader.readLine())!=null){
String[] lines = line.split(" ");
for (String word : lines) {
if(wordMap.containsKey(word)){
int value = wordMap.get(word);
wordMap.put(word, value+=1);
}else{
wordMap.put(word, 1);
}
}
}
bReader.close();//釋放資源
}catch (IOException ex){
System.out.println(ex.getMessage());
}
});
System.out.println("=====Java詞頻統計結果列印輸出======");
System.out.println(wordMap);
for(Map.Entry<String,Integer> result:wordMap.entrySet()){
System.out.println("單詞:"+result.getKey()+",個數:"+result.getValue());
}
}
}
Java大家都是很熟悉了吧,因此寫起來demo毫不費勁,總體下來還是一氣呵成的,程式碼不做過多解釋,唯一需要說明的就是demo中採用了Java8的特性 -- forEach(很方便)
我們看下執行的結果:
================Java=============
F:\wordcount\1.txt
F:\wordcount\2.txt
F:\wordcount\3.txt
F:\wordcount\4.txt
=====Java詞頻統計結果列印輸出======
{a=8, b=8, c=12, d=8, e=8, f=4}
單詞:a,個數:8
單詞:b,個數:8
單詞:c,個數:12
單詞:d,個數:8
單詞:e,個數:8
單詞:f,個數:4
(2) Scala demo實現
package com.appleyk.scala
import java.io.File
import scala.io.Source
object SWordCount{
def main(args: Array[String]): Unit = {
System.out.println("================Scala=============")
val path = "F:\\wordcount" //目錄url
val dirFile = new File(path) //混搭Java程式碼,new一個file物件,該物件是一個目錄
val files = dirFile.listFiles //列出file目錄下的所有檔案【Java中是一個file陣列】
//遍歷files物件【陣列】
for(file <- files) println(file)
// 將files物件轉化為List集合
val fileList = files.toList
// Scala中使用不可變的對映。如果想使用可變集,必須明確地匯入scala.collection.mutable.Map類
// wordMap變數不可變,但是其指向的卻是一個可變的Map集合,鍵值對 --> key:String -> value:Int
val wordMap = scala.collection.mutable.LinkedHashMap[String,Int]()
// 遍歷【非常恐怖,三次foreach搞定詞頻統計!!!】
fileList foreach(file=> Source.fromFile(file).getLines() //從file裡面讀取二進位制流,並獲取流的行資料列表
.foreach(line=>line.split(" ") // 每一行資料根據空格分割成words列表
.foreach(word=>{
//判斷word【單詞】是否在map裡
if(wordMap.contains(word)){
wordMap(word)+=1 // 有的話,計數器(key對應的value)+1
}else{
wordMap+=(word -> 1) // 否則的話,將單詞word加進map集合中,並初始化value=1
}
})
))
printf("=====C編碼風格的輸出【詞頻統計結果列印】======%s","\n")
System.out.println(wordMap)
for((k,v) <- wordMap) printf("單詞:%s,個數:%d \n",k,v)
}
}
由於Scala執行於Java平臺(Java虛擬機器)上,併相容現有的Java程式,因此,我們在編碼的時候也可以混搭著Java的程式碼;同時,我們對比發現,Scala的編碼風格真的很隨意,可以【物件 空格 foreach】也可以使用【物件.foreach】的方式進行列表的遍歷,同時,其支援lambda表示式【匿名函式】,結合foreach,我們可以利用很少的程式碼將整個需求給實現出來,而且map集合的for迴圈列印出key-value鍵值對也是很輕鬆的,比較Java,Scala確實很棒,博主在學習Scala語言的時候,發現其和Python的語法有些像,所謂語言都是相通的,學好一門語言,其他語言基本上都能很快入手,不多說,我們看下Scala執行的效果:
================Scala=============
F:\wordcount\1.txt
F:\wordcount\2.txt
F:\wordcount\3.txt
F:\wordcount\4.txt
=====C編碼風格的輸出【詞頻統計結果列印】======
Map(a -> 8, b -> 8, c -> 12, d -> 8, e -> 8, f -> 4)
單詞:a,個數:8
單詞:b,個數:8
單詞:c,個數:12
單詞:d,個數:8
單詞:e,個數:8
單詞:f,個數:4
需要說明下,使用Map集合,最後的結果是亂序的,因此demo中使用了LinkedHashMap【有序Map】
(3) Python demo實現
#!/usr/bin/env Python3
# -*- encoding:utf-8 -*-
import os #匯入os模組,並使用該模組呼叫系統命令,獲得路徑,作業系統的型別等
if __name__=="__main__":
print("================Pyhton=============")
path="F:\\wordcount" #目錄url
filenames = os.listdir(path) #os.listdir() 方法用於返回指定的資料夾包含的檔案或資料夾的名字的列表,注意是名字
#拿到檔案的全路徑名稱集合
filefullnames = [os.path.join(path,filename) for filename in filenames]
for name in filefullnames:
print(name)
#遍歷檔名列表+完整路徑拼接+生成檔案物件列表
fileList = [open(filefullname) for filefullname in filefullnames]
#上面的生成式的當時等價於下面的for程式碼塊
# for filename in filenames:
# filename = os.path.join(path,filename) #檔案完整路徑拼接
# fileList.append(open(filename,'r')) #新增檔案物件
wordMap = {} #定義一個單詞的字典【dict】集合
#遍歷檔案物件列表
for file in fileList:
for line in file: #讀取檔案中的每一行
words = line.strip('\n').split(" ") #消除換行符,並對每一行資料進行空格分割
for word in words: #遍歷單詞列表
if wordMap.get(word) is not None: #如果字典表裡麵包含了單詞word
wordMap[word]+=1 #出現頻率+1
else:
wordMap[word]=1 #新增一個單詞,初始化頻率為1
file.close() #釋放資源
print("=====Python詞頻統計結果列印輸出======")
print(wordMap)
for key in wordMap.keys():
print("單詞:%s,個數:%d" %(key,wordMap.get(key)))
如果說Scala在對變數的型別沒有太大要求的話【val:不可變,var:可變,但是型別是自動匹配的】的話,那麼Python對變數簡直就是沒有要求,你不需要給變數指定什麼String型別、Int型別或者是指定變數是val可變的還是var不可變的,其變數的賦值操作就是變數宣告和定義的過程,因此,在宣告一個變數的時候,必須先賦值
而且Python有列表生成式,可以很方便的根據條件生成我們最終想要的結果列表,如下:
利用列表生成式再結合條件過濾,生成一個偶數序列
demo中,我們利用列表生成式(List generation)的特性拿到了檔案的完整路徑列表,如下
更多生成式的用法,可以參考我的博文:Python3學習(9)--列表生成式(List generation)
.....................................................話不多說,我們直接執行demo,看一下pyhton的執行情況
================Pyhton=============
F:\wordcount\1.txt
F:\wordcount\2.txt
F:\wordcount\3.txt
F:\wordcount\4.txt
=====Python詞頻統計結果列印輸出======
{'a': 8, 'b': 8, 'c': 12, 'd': 8, 'e': 8, 'f': 4}
單詞:a,個數:8
單詞:b,個數:8
單詞:c,個數:12
單詞:d,個數:8
單詞:e,個數:8
單詞:f,個數:4
四、最後
通過對比,我們可以看出,在程式碼簡潔程度上,Scala和Python那是旗鼓相當啊,但如果只能選一個的話,那非Pyhton莫屬了!
而且,Python寫起demo來比較嗨皮,,Java則是中規中矩的老大哥,Scala由於是分散式計算框架Spark的實現語言,因此,
Scala我們可以稍微瞭解一下,語言都是相通的,建議多掌握幾門輔助語言,這樣有利於日常工作的順利開展
相關文章
- python如何統計詞頻Python
- python實現詞頻統計Python
- 詞語詞頻統計
- 詞頻統計
- 詞頻統計mapreduce
- Python統計四六級考試的詞頻Python
- scala陣列與java陣列對比陣列Java
- python TK庫 統計word文件單詞詞頻程式 UI選擇文件PythonUI
- python 計算txt文字詞頻率Python
- 用Python如何統計文字檔案中的詞頻?(Python練習)Python
- PostgreSQL全文檢索-詞頻統計SQL
- 文字挖掘之語料庫、分詞、詞頻統計分詞
- 詞頻統計任務程式設計實踐程式設計
- Java Go python 執行速度對比JavaGoPython
- Spark-stream基礎---sparkStreaming和Kafka整合wordCount單詞計數SparkKafka
- python 實現中文分詞統計Python中文分詞
- Javafx-【直方圖】文字頻次統計工具 中文/英文單詞統計Java直方圖
- 統計英文名著中單詞出現頻率
- Python實踐之合併WOS文獻資料,並對關鍵詞進行詞頻分析Python
- hadoop學習筆記:執行wordcount對檔案字串進行統計案例Hadoop筆記字串
- hadoop之旅6-windows本地MapReducer離線單詞統計HadoopWindows
- 兩個coca略有不同詞頻檔案 比較
- Ansj與hanlp分詞工具對比HanLP分詞
- python做頻率統計圖 完整版Python
- Java 多執行緒讀取檔案並統計詞頻 例項 出神入化的《ThreadPoolExecutor》Java執行緒thread
- Python==與is對比Python
- 10 Python物件導向程式設計:類和物件以及和Java的對比Python物件程式設計Java
- JAVA程式設計習慣之equals對比Java程式設計
- WordCount
- Python視覺化-generate_from_frequencies給定詞頻畫詞雲圖(WordCloud)Python視覺化Cloud
- LeetCode題解(0692):前K個高頻單詞(Python)LeetCodePython
- java排序方式對比Java排序
- Kotlin 與 Java 對比KotlinJava
- MapReduce 程式設計模型 & WordCount 示例程式設計模型
- 【csp202403-1】詞頻統計【第33次CCF計算機軟體能力認證】計算機
- Python 和 c++/c/java 對於負數的儲存方式對比PythonC++Java
- JAVA垃圾回收機制和Python垃圾回收對比與分析JavaPython
- 熱詞統計分析