作业 4:词频统计——基本功能
一、基本信息
1、本次作業(yè)的地址:https://edu.cnblogs.com/campus/ntu/Embedded_Application/homework/2088
2、項目Git地址:https://gitee.com/ntucs/PairProg/tree/SE034_035/
二、項目分析
(1)程序運行模塊(方法、函數(shù))介紹
①任務(wù)一:給定一段英文字符串文件,統(tǒng)計其中各個英文單詞的出現(xiàn)頻率,將結(jié)果輸入result.txt文件
# filename: WordCount.py
# 注意:代碼風(fēng)格
import argparse
import re
import cProfile
import pstats
from string import punctuation
def process_file(dst): # 讀文件到緩沖區(qū)
try: # 打開文件
d = open(dst, "r")
except IOError as s:
print(s)
return None
try: # 讀文件到緩沖區(qū)
bvffer = d.read()
except:
print('Read File Error!')
return None
d.close()
return bvffer
def process_transform(bvffer): # 將文本中的大寫轉(zhuǎn)換為小寫且進(jìn)行非法字符的轉(zhuǎn)換
if bvffer:
bvffer = bvffer.lower() # 將文本中的大寫字母轉(zhuǎn)換為小寫
for ch in '{}!"#%()*+-,-./:;<=>?&@“”[]^_|':
bvffer = bvffer.replace(ch, " ") # 將文本中非法字符轉(zhuǎn)化為空格
words = bvffer.split() # 用空格分割字符串
return words
def process_rowCount(bvffer): # 計算文章的行數(shù)
if bvffer:
count = 1
for word in bvffer: # 開始計數(shù)
if word == '
':
count = count + 1
print("lines:{:}".format(count))
f = open('result.txt', 'w')
print("lines:{:}".format(count),file=f)
f.close()
def process_wordNumber(words): # 通過正則表達(dá)式證明是否符合單詞標(biāo)準(zhǔn),計算單詞個數(shù)且返回單詞字典
if words:
wordNew = []
words_select = '[a-z]{4}(w)*'
for i in range(len(words)):
word = re.match(words_select, words[i]) # 如果不匹配,返回NULL類型
if word:
wordNew.append(word.group())
print("words:{:}".format(len(wordNew)))
f = open('result.txt', 'a')
print("words:{:}".format(len(wordNew)),file=f)
f.close()
return wordNew
def process_stopwordSelect(words, stopwords):
word_freq = {}
# 統(tǒng)計每個單詞的頻率,存放在字典word_freq
for word in words: # 開始計數(shù),將轉(zhuǎn)換好的words中踢除stopwords.txt中的單詞
if word in stopwords:
continue
else:
word_freq[word] = word_freq.get(word, 0) + 1 # 將符合的單詞進(jìn)行計數(shù)統(tǒng)計
return word_freq
def output_result(word_freq):
if word_freq:
sorted_word_freq = sorted(word_freq.items(), key=lambda v: v[1], reverse=True)
for item in sorted_word_freq[:10]: # 輸出 Top 10 頻率高的
print("<{:}>:{:}".format(item[0], item[1]))
f = open('result.txt','a')
print("<{:}>:{:}".format(item[0], item[1]), file=f)
f.close()
def main():
#dst_Aimtxt = 'src/Gone_with_the_wind.txt'
dstSecond = 'src/stopword.txt'
parser = argparse.ArgumentParser()
parser.add_argument('dst')
args = parser.parse_args()
dst = args.dst
bvfferOne = process_file(dst) # 讀目標(biāo)txt文件
bvfferSecond = process_file(dstSecond) # 讀stopword.txt文件
process_rowCount(bvfferOne) # 讀目標(biāo)txt文件的文章有多少行
bvffertransformOne = process_transform(bvfferOne) # 將目標(biāo)txt文件中的文章文體及字符轉(zhuǎn)換
bvffertransformSecond = process_transform(bvfferSecond) # 將stopword.txt文件中的文章文體及字符轉(zhuǎn)換
wordNew = process_wordNumber(bvffertransformOne) # 計算目標(biāo)txt文件中單詞的個數(shù)
word_freq = process_stopwordSelect(wordNew, bvffertransformSecond) # 輸出轉(zhuǎn)換好的words中踢除stopwords.txt中的前10個單詞
output_result(word_freq)
if __name__ == "__main__":
# 把分析結(jié)果保存到文件中
cProfile.run("main()", filename="result.wordcount")
# 創(chuàng)建Stats對象
p = pstats.Stats("result.wordcount")
# 按調(diào)用的次數(shù)進(jìn)行排序,打印前10行
p.strip_dirs().sort_stats("calls").print_stats(10)
# 按照運行時間和函數(shù)名進(jìn)行排序,打印前10行
p.strip_dirs().sort_stats("cumulative", "name").print_stats(10)
# 如果想知道有哪些函數(shù)調(diào)用了process_transform
p.print_callers(0.5, "process_transform")
# 如果想知道有哪些函數(shù)調(diào)用了process_rowCount
p.print_callers(0.5, "process_rowCount")
# 如果想知道有哪些函數(shù)調(diào)用了process_wordNumber
p.print_callers(0.5, "process_wordNumber")
# 如果想知道有哪些函數(shù)調(diào)用了process_stopwordSelect
p.print_callers(0.5, "process_stopwordSelect")
# 如果想知道有哪些函數(shù)調(diào)用了process_twoPhrase
p.print_callers(0.5, "process_twoPhrase")
# 如果想知道有哪些函數(shù)調(diào)用了process_threePhrase
p.print_callers(0.5, "process_threePhrase")
# 如果想知道有哪些函數(shù)調(diào)用了output_result
p.print_callers(0.5, "output_result")
# 查看process_buffer()函數(shù)中調(diào)用了哪些函數(shù)
#p.print_callees("process_buffer")
(1.1)統(tǒng)計文件的有效行數(shù)。
通過文章中換行最后都會出現(xiàn)字符”
“來進(jìn)行統(tǒng)計的。
def process_rowCount(bvffer): # 計算文章的行數(shù)
if bvffer:
count = 1
for word in bvffer: # 開始計數(shù)
if word == '
':
count = count + 1
print("lines:{:}".format(count))
(1.2)統(tǒng)計文件的單詞總數(shù)。
通過正則表達(dá)式來證明是否符合單詞的標(biāo)準(zhǔn),最后輸出一個全是符合單詞標(biāo)準(zhǔn)的List表
【正則表達(dá)式參考:https://blog.csdn.net/mark555/article/details/22379757
和 https://baike.baidu.com/item/%E6%AD%A3%E5%88%99%E8%A1%A8%E8%BE%BE%E5%BC%8F/1700215】
def process_wordNumber(words): # 通過正則表達(dá)式證明是否符合單詞標(biāo)準(zhǔn),計算單詞個數(shù)且返回單詞字典
if words:
wordNew = []
words_select = '[a-z]{4}(w)*'
for i in range(len(words)):
word = re.match(words_select, words[i]) # 如果不匹配,返回NULL類型
if word:
wordNew.append(word.group())
print("words:{:}".format(len(wordNew)))
(1.3)統(tǒng)計文件中各單詞的出現(xiàn)次數(shù),最終只輸出頻率最高的10個。頻率相同的單詞,優(yōu)先輸出字典序靠前的單詞。
在統(tǒng)計單詞的出現(xiàn)頻率的時候,我們還加入了停詞表stopword.txt,計數(shù)轉(zhuǎn)換好且都符合單詞標(biāo)準(zhǔn)的List表,并且剔除stopword.txt中的單詞頻率。
def process_stopwordSelect(words, stopwords):
word_freq = {}
# 統(tǒng)計每個單詞的頻率,存放在字典word_freq
for word in words: # 開始計數(shù),將轉(zhuǎn)換好的words中踢除stopwords.txt中的單詞
if word in stopwords:
continue
else:
word_freq[word] = word_freq.get(word, 0) + 1 # 將符合的單詞進(jìn)行計數(shù)統(tǒng)計
return word_freq
②任務(wù)一:通過停詞表stopword.txt去剔除一些無用的單詞(例如“there”、“was”等);統(tǒng)計高頻詞組。
我們已經(jīng)在任務(wù)一上已經(jīng)將停詞表應(yīng)用了,下面著重講訴統(tǒng)計高頻詞組。我們在統(tǒng)計高頻詞組時候是在任務(wù)一的基礎(chǔ)上將統(tǒng)計高頻詞組進(jìn)行封裝,下面只展示封裝部分。
我們的想法是:將轉(zhuǎn)換為小寫、去除非法字符且都滿足單詞標(biāo)準(zhǔn)的單詞兩兩組合或者三個三個組合,最后達(dá)到統(tǒng)計的效果。
def process_twoPhrase(words):
useless_twoPhrase =['they were','would have','there were','have been','that would']
words_group = []
for i in range(len(words) - 1):
str = '%s %s' % (words[i], words[i + 1])
words_group.append(str)
word_freq = {}
for word in words_group:
if word in useless_twoPhrase:
continue
else:
word_freq[word] = word_freq.get(word, 0) + 1 # 將詞組進(jìn)行計數(shù)統(tǒng)計
return word_freq
def process_threePhrase(words):
words_group = []
for i in range(len(words) - 2):
str = '%s %s %s' % (words[i], words[i + 1], words[i + 2])
words_group.append(str)
word_freq = {}
for word in words_group:
word_freq[word] = word_freq.get(word, 0) + 1 # 將詞組進(jìn)行計數(shù)統(tǒng)計
return word_freq
(2)程序算法的時間、空間復(fù)雜度分析。
(2.1)程序算法的時間
①任務(wù)一:
②任務(wù)二:
(2.2)空間復(fù)雜度分析
就process_twoPhrase()這個函數(shù)而言,里面有兩個for循環(huán),而且for循環(huán)內(nèi)部也沒有循環(huán)。我們可以大致估計空間復(fù)雜度為O(N+n)。
(3)程序運行案例截圖。
①任務(wù)一:
②任務(wù)二:
三、性能分析
(1)調(diào)用的函數(shù)次數(shù)進(jìn)行排序,輸出前10行
(2)性能圖表
四、結(jié)對編程開銷時間及照片
(1)結(jié)對編程開銷時間花費了一周時間左右。
(2)結(jié)對編程照片
五、事后分析與總結(jié)
(1)對某個問題的討論決策過程
我們在統(tǒng)計高頻詞組的時候,當(dāng)時討論了兩種統(tǒng)計高頻詞組的方法:一、單詞兩兩結(jié)合,三個三個結(jié)合;二、利用正則表達(dá)式進(jìn)行統(tǒng)計。接著,我們還討論是不是在統(tǒng)計高頻詞組的時候是否也需要停詞表。
(2)評價對方
陳原對周怡峰的評價:周怡峰在編程方面基礎(chǔ)非常不錯,而且在合作的過程中積極為項目做巨大的貢獻(xiàn),在查閱資料與學(xué)習(xí)方面不遺余力。非常有自己的想法,為我們的編程帶來了很多動力和樂趣,與之合作非常愉快。
周怡峰對陳原的評價:陳原編寫了大部分的代碼,在學(xué)習(xí)能力方面十分出色,從閱讀python書籍到可以編寫代碼用了4-5天的時間,積極思考問題,我不會的地方會提供幫助。在寫博客時也非常追求完美,希望下次合作。
(3)評價整個過程:關(guān)于結(jié)對過程的建議
對于結(jié)對編程,我們應(yīng)該在結(jié)束之后積極思考它與我們單獨編程有什么區(qū)別。這次鍛煉也給我們提供了一次很好的經(jīng)歷,在結(jié)對編程中我們都要積極參與,這樣我們才能積極積累很多經(jīng)驗,也學(xué)到了很多,希望我們以后能有更多的機(jī)會進(jìn)行結(jié)對編程。
總結(jié)
以上是生活随笔為你收集整理的作业 4:词频统计——基本功能的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 余罪电视剧剧情介绍
- 下一篇: 除了sum求和函数除了sum求和还有什么