2019-10-24(python第四天)(中)

【练习】读取红楼梦小说,并且绘制该小说的整篇词云

大致思路:

# 第一步:引入相关库
# 第二步:读取文件
# 第三步:分词
#   引用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
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。