题目如下:
#我使用的文档不是题目中的文件,是我自己创建的文档。
一共需要两个文件,一个是.docx,一个是stopwords.txt
1.必须使用python的docx库,注意!!!!!一定是python -docx而不是docx。
2.统计中文需要下载jieba库,直接使用pip install jieba即可,若满红报错,使用国内镜像源下载 pip install -i https://pypi.tuna.tsinghua.edu.cn/simple jieba 。
3.需要使用collections库的Counter进行统计。
4.使用openpyxl库的Workbook创建工作簿,将最后的统计结果存储在excel表格中。
from docx import Document
import jieba
from collections import Counter
import openpyxl
#使用jieba库进行中文分词,使用collections库中的Counter类统计词频
if __name__ == '__main__':
#第一步,读取停用词有哪些,为后续的判断做准备
StopName = open("stopwords.txt",'r',encoding='utf-8') #打开停用词的文档
Stop_Words = StopName.read() #读取停用词
# print(Stop_Words) #将停用词打印出来检查是否读取
#第二步,读取word文档,将其保存在txt文档中
Doc = Document("朱自清散文选集.docx") #创建对象
#将doc文件转为txt文件
with open("朱自清散文选集.txt",'w',encoding="utf-8") as Word_File:
for para in Doc.paragraphs: #使用paragraphs读取docx文件段落
# print(para.text) #打印检验
Word_File.write(para.text + "\n") #将段落存储分行
#第三步,切割txt文件的内容 f = open(Word_File,'r',encoding='utf-8')
txt = open("朱自清散文选集.txt","r", encoding='utf-8').read() #读取文件内容
words = jieba.lcut(txt) #使用jieba库的lcut方法进入精确模式划分,如果想要使用全模式就加上参数cut_all = True(默认为False)
#并且自动返回一个列表类型
print("-----划分后的词组为:-----") #打印检查
print(words)
#第四步,遍历停用词表,判断是否有停用词,若有则删除。
li = [] #使用一个新列表保存去掉停用词的内容
#可以使用for循环也可以使用filter函数
# 1.filter函数
print("-----方法一:使用filter函数,去掉停用词后的词组为:-----")
#filter函数有两个参数,function和可迭代对象,直接使用lambda函数。
lst = filter(lambda x:x not in Stop_Words,words) #返回值为迭代器
lt = list(lst) #得到一个可迭代对象
print(list(lst))
# 2.for循环
print("-----方法二:使用for循环,去掉停用词后的词组为:-----")
for word in words:
if word not in Stop_Words:
li.append(word)
print(list(li))
#第五步,统计词频
counter = Counter(li) #创建Counter对象进行词频的统计,Counter的对象是一个dic的子类。
phrase = []
for word,num in counter.items(): #调用dic的items方法
phrase.append((word,num)) #以元组类型添加到列表当中去
print("-----统计的词频为:-----")
print(phrase)
#第六步,将统计的词频保存到Excel表格当中
wb = openpyxl.Workbook() #创建工作薄
ws = wb.active #由于在创建工作簿的同时也创建一个工作表,所以使用active直接调用该工作表
#将出现的词语和词频写入表格
#定义表头
ws['A1'] = "词组"
ws['B1'] = "词频"
#循环进行索引添加
for i, row in enumerate(phrase):#i为循环的索引,row对应phrase列表里面的索引位置的值
#由于i是从0开始的,所以需要将i+2作为行数
ws['A{}'.format(i+2)] = row[0] #表示会将row中的第一个元素放入工作表的A列
ws['B{}'.format(i+2)] = row[1] #将row中的第二个元素放入工作表的B列
wb.save("词频统计表.xlsx") #储存
Ten_max = counter.most_common(10) #Counter对象的most_common方法可以直接调用,统计词频最高的十个词语并输出
"""关于该方法的解释:
List the n most common elements and their counts from the most common to the least.
If n is None, then list all element counts.
"""
print(Ten_max) #输出结果
结果如下:
以下为相关知识点:
1.读取stopwords.txt文件:
可以直接使用open来打开文件,也可以使用with open,使用只读模式r
需要将打开的stopwords.txt文件储存在Stop_Words中,所以使用read()方法对文件内容进行全文读取。该方法返回字符串。
#使用read读取内容
#直接open打开
stop_file = open("stopwords.txt","r",encoding="utf-8")
stop_words = stop_file.read()
#使用with open打开
with open("stopwords.txt","r",encoding="utf-8") as stop_file:
stop_words = stop_file.read()
#使用readline也可以
2.将word文档内容读取到txt中:
由于jieba库不能对.docx文件进行操作,只能对txt进行操作,所以需要先将.docx转化为.txt
首先需要使用docx的Document()方法初始化一个对象,然后用with open()直接新建一个.txt文件,记为Word_File。
利用docx包的paragraphs,使用for循环获取.docx文档的段落,存储在新创建的.txt文件中。
Doc = Document("朱自清散文选集.docx") #创建对象
#将doc文件转为txt文件
with open("朱自清散文选集.txt",'w',encoding="utf-8") as Word_File:
for para in Doc.paragraphs: #使用paragraphs读取docx文件段落
# print(para.text) #打印检验
Word_File.write(para.text + "\n") #将段落存储分行
3.使用jeiba库切割中文词组:
若要对文件星星分词切割,我们首先需要先打开文件。打开刚刚创建的新.txt文件。
注意:在此处打开文件一定不要使用刚刚定义的文件变量Word_File,要么使用绝对路径要么直接使用刚刚创建的新文件的文件名。
接下来使用jieba库进行词组的分割。
首先要了解jieba库的划分词组的方法:
cut_all的默认值为False
txt = open("朱自清散文选集.txt","r", encoding='utf-8').read() #读取文件内容
words = jieba.lcut(txt)
#使用jieba库的lcut方法进入精确模式划分,如果想要使用全模式就加上参数cut_all = True(默认为False)
#并且自动返回一个列表类型
print("-----划分后的词组为:-----") #打印检查
print(words)
4.排除停用词:
一共有两种方法,比较通俗的方法是使用for循环。
li = [] #使用一个新列表保存去掉停用词的内容
for word in words:
if word not in Stop_Words: #使用not in判断变量是否存在
li.append(word)
print(list(li))
方法二:使用filter()函数进行停用词的过滤。
filter() 函数用于过滤序列,过滤掉不符合条件的元素,返回由符合条件元素组成的新列表。
该接收两个参数,第一个为函数,第二个为序列,序列的每个元素作为参数传递给函数进行判断,然后返回 True 或 False,最后将返回 True 的元素放到新列表中。
语法:
filter(function, iterable) #function是判断函数,itrtable是可迭代对象
注意:在此处我还使用了lambda函数。
lambda 函数是一种小型、匿名的、内联函数,它可以具有任意数量的参数,但只能有一个表达式。
匿名函数不需要使用 def 关键字定义完整函数。
lambda 函数通常用于编写简单的、单行的函数,通常在需要函数作为参数传递的情况下使用,例如在 map()、filter()、reduce() 等函数中。
语法:
lambda arguments: expression
arguments
是参数列表,可以包含零个或多个参数,但必须在冒号(:
)前指定。expression
是一个表达式,用于计算并返回函数的结果。
#filter函数有两个参数,function和可迭代对象,直接使用lambda函数。
lst = filter(lambda x:x not in Stop_Words,words) #返回值为迭代器
lt = list(lst) #得到一个可迭代对象
print(list(lst))
注意:在此处一定要分清楚可迭代对象和迭代器!我们可以使用list()获取迭代器里的元素生成一个list可迭代对象。
关于可迭代对象(iterable)和迭代器(iterator)的关系和区别可参考下文:
【Python】详解 可迭代对象 (iterable) 与 迭代器 (iterator) —— 迭代器完全解读(上)_可迭代对象可以无限迭代-CSDN博客
Python详解可迭代对象(Iterable)、序列(Sequence)、迭代器(Iterator)、生成器(generator)_可迭代序列-CSDN博客
5.使用collection库的Counte类统计词频:
Counter可以统计可迭代序列中每个元素的个数。
若使用filter()方法获取过滤词组序列,则必须将其得到的内容存放在可迭代序列中。
首先需要创建一个Counter的对象counter,再创建一个新列表phrase用来存放得到的词频数据。
用for循环进行遍历,调用字典的items()方法,返回可遍历的(键, 值) 元组数组。(Counter的对象是字典的子类)
使用append()方法添加元素。
counter = Counter(li) #创建Counter对象进行词频的统计,Counter的对象是一个dic的子类。
phrase = []
for word,num in counter.items(): #调用dic的items方法
phrase.append((word,num)) #以元组类型添加到列表当中去
print("-----统计的词频为:-----")
print(phrase)
要想了解更多关于collections的Counter类,可以看下面这篇文章:
Python计数器collections.Counter用法详解_.collect()和..count()-CSDN博客
关于统计词频的遍历方法,除了使用Counter类,还有别的方法:
https://blog.51cto.com/u_14246112/3140581
6.生成Excel表格存放数据:
导入openpyxl包使用load_Workbook创建新的工作簿,然后使用active激活。
将表格中的A1和B1表头设为“词组”、“词频”。
使用enumerate()函数遍历得到的统计列表。其中循环变量i表示循环的索引即元素下标,row对应phrase列表里面的索引位置的元素的值。
在for循环中使用format()函数将对应元素的值存入相应单元格中。基本语法如下:
"{} {}".format("hello", "world") # 不设置指定位置,按默认顺序 'hello world'
需要注意的是,format后面的参数会返回到{}中,所以'A{}.format(i+2)'意味着在A列的i+2行填入数据row[0](词组),同理,在B列的i+2行填入数据row[1](词频)
由于i=0行是表头,i=1行是“词组”“词频”参数,所以我们设置从i=2行开始填入。
将数据导入后,要记得保存.save()
wb = openpyxl.Workbook() #创建工作薄
ws = wb.active #由于在创建工作簿的同时也创建一个工作表,所以使用active直接调用该工作表
#将出现的词语和词频写入表格
#定义表头
ws['A1'] = "词组"
ws['B1'] = "词频"
#循环进行索引添加
for i, row in enumerate(phrase):#i为循环的索引,row对应phrase列表里面的索引位置的值
#由于i是从0开始的,所以需要将i+2作为行数
ws['A{}'.format(i+2)] = row[0] #表示会将row中的第一个元素放入工作表的A列
ws['B{}'.format(i+2)] = row[1] #将row中的第二个元素放入工作表的B列
wb.save("词频统计表.xlsx") #储存
7.输出词频最大的十个词语:
调用Counter里面的most_common()函数。
英文释义为:列出 n 个最常见的元素及其从最常见到最少的计数。如果 n 为 None,则列出所有元素计数。
Ten_max = counter.most_common(10) #Counter对象的most_common方法可以直接调用,统计词频最高的十个词语并输出
"""关于该方法的解释:
List the n most common elements and their counts from the most common to the least.
If n is None, then list all element counts.
"""
print(Ten_max) #输出结果