【练习】读取红楼梦小说,并且绘制该小说的整篇词云
大致思路:
# 第一步:引入相关库
# 第二步:读取文件
# 第三步:分词
# 引用jieba模块
# 第四步:构造一个容器存储需要的数据
# 定义一个空容器(空字典)
# 向字典里更新数据
# 第五步:(步骤提前)删除重复词和无关词
# 对指向同一个人的词进行合并
# 构建一个集合,定义无关词
# 删除无关词
# 第六步:排序筛选
# 把字典转化为列表
# 按照词频次数进行排序
# 显示出现词频前10的词
# 定义一个空列表,存放前十的人物名
# 拆包
# 定义role和count
# 添加role
# 把列表变成字符串
# 第七步:显示
# 引用WordCloud模块
具体做法:
# 引入相关库:
import jieba
from wordcloud import WordCloud
import imageio
mask = imageio.imread('china.jpg') # 引入面具(词云的背景图片)
# 第一步:读取文件
with open('hongloumeng.txt', 'r', encoding='UTF-8') as f: # 引入with语句,以只读的方式打开hongloumeng.txt文件,默认编码方式为UTF-8
data = f.read() # 把读取到的数据存放到data中
print(data) # 输出data(即输出整篇小说)
# 第二步:分词
word_list = jieba.lcut(data) # 引用jieba模块进行精确分词
print(word_list) # 输出经过分词后data
# 第三步:构造一个容器存储需要的数据(第一次筛选)
counts = {} # 定义一个空容器(空字典),用来存放需要的数据
for word in word_list: # 遍历word_list里的每个字词
if len(word) <= 1: # 如果这个字词的长度小于或等于1时,
continue # 跳出本层判断,继续遍历
else: # 否则(当这个字词的长度大于1时)
counts[word] = counts.get(word, 0) + 1 # 向字典里更新数据,用get()方法把该字词写进counts字典里(对进行计数word出现的频率进行统计,当word不在words_list时,返回值是0;当word在words中时,返回+1,以此进行累计计数。)
print(counts) # 输出经过字词长度筛选后,word_list中剩下的符合要求的字词
# 第四步:(步骤提前)合并重复词和删除无关词(第三次筛选)
# # 对指向同一个人的词进行合并
counts['贾母'] = counts['贾母'] + counts['老太太']
# # 构建一个集合,定义无关词
ex_others = {'什么', '一个', '我们', '你们',
'如今', '说道', '姑娘', '起来',
'这里', '出来', '知道', '众人',
'那里', '自己', '一面', '只见',
'两个', '奶奶', '太太', '没有',
'怎么', '不是', '不知', '这个',
'听见', '这样', '进来', '咱们',
'就是', '东西', '告诉', '老太太',
'回来', '只是', '大家', '老爷',
'只得', '丫头', '这些', '他们',
'不敢', '出去', '所以'}
# # 对无关词进行删除
for word in ex_others: # 遍历ex_others无关词集合
del counts[word] # 对应删除counts里面的字词
# 第五步:排序筛选(第二次筛选)
print(counts.items()) # 输出字典里全部键值对
items = list(counts.items()) # 把字典转化为列表: 定义一个新的列表new_list,强制转换“字典里全部键值对”且赋值给new_list(相当于把数据传进去)
print(items) # 输出列表形式的键值对(即[], [], ...)
items.sort(key=lambda x: x[1], reverse=True) # 定义匿名函数,按照“x[1]词频次数”进行倒序排序
print(items) # 输出经过倒序处理的列表items
role_list = [] # 定义一个空列表,存放前十的人物名
# # 拆包,显示出现词频前10的词
for i in range(10): # 遍历10次循环
role, count = items[i] # 定义role和count,每遍历一次,就把列表items中相对应的元组里的两个值分别赋值给role和count
print(role, count) # 每次遍历输出items中元组相对应的role值和count值
for _ in range(count): # 嵌套,在执行上一步遍历分别得出一个role和count值时,再对其中的count值作为本层嵌套中遍历的次数限制(最大次数)
role_list.append(role) # 每遍历一次,就往role_list里添加一次role的值,直到count达到最大值,退出本层,返回到上一层继续遍历。
print(role_list) # 输出一个“role人物名”的列表,每个role出现的次数为count,且为从大到小的顺序排序
text = ' '.join(role_list) # 把列表变成字符串
print(text) # 输出字符串形式的role_list列表
# 第六步:显示
# # 引用WordCloud模块
WordCloud(
background_color='white',
font_path='msyh.ttc',
mask=mask,
collocations=False
).generate(text).to_file('红楼们前十人物排名.png')
效果如下:
红楼们前十人物排名.png