如何用Python来理一理红楼梦里的那些关系


Posted in Python onAugust 14, 2019

前言

今天,一起用 Python 来理一理红楼梦里的那些关系

不要问我为啥是红楼梦,而不是水浒三国或西游,因为我也鉴定的认为,红楼才是无可争议的中国古典小说只巅峰,且不接受反驳!而红楼梦也是我多次反复品读的为数不多的小说,对它的感情也是最深的。

好了,不酸了,开干。

数据准备

红楼梦 TXT 文件一份

金陵十二钗 + 贾宝玉 人物名称列表

人物列表内容如下:

宝玉 nr
黛玉 nr
宝钗 nr
湘云 nr
凤姐 nr
李纨 nr
元春 nr
迎春 nr
探春 nr
惜春 nr
妙玉 nr
巧姐 nr
秦氏 nr

这份列表,同时也是为了做分词时使用,后面的 nr 就是人名的意思。

数据处理

读取数据并加载词典

with open("红楼梦.txt", encoding='gb18030') as f:
    honglou = f.readlines()
  jieba.load_userdict("renwu_forcut")
  renwu_data = pd.read_csv("renwu_forcut", header=-1)
  mylist = [k[0].split(" ")[0] for k in renwu_data.values.tolist()]

这样,我们就把红楼梦读取到了 honglou 这个变量当中,同时也通过 load_userdict 将我们自定义的词典加载到了 jieba 库中。

对文本进行分词处理并提取

tmpNames = []
  names = {}
  relationships = {}
  for h in honglou:
    h.replace("贾妃", "元春")
    h.replace("李宫裁", "李纨")
    poss = pseg.cut(h)
    tmpNames.append([])
    for w in poss:
      if w.flag != 'nr' or len(w.word) != 2 or w.word not in mylist:
        continue
      tmpNames[-1].append(w.word)
      if names.get(w.word) is None:
        names[w.word] = 0
      relationships[w.word] = {}
      names[w.word] += 1
  • 首先,因为文中"贾妃", "元春","李宫裁", "李纨" 混用严重,所以这里直接做替换处理。
  • 然后使用 jieba 库提供的 pseg 工具来做分词处理,会返回每个分词的词性。
  • 之后做判断,只有符合要求且在我们提供的字典列表里的分词,才会保留。
  • 一个人每出现一次,就会增加一,方便后面画关系图时,人物 node 大小的确定。
  • 对于存在于我们自定义词典的人名,保存到一个临时变量当中 tmpNames。

处理人物关系

for name in tmpNames:
    for name1 in name:
      for name2 in name:
        if name1 == name2:
          continue
        if relationships[name1].get(name2) is None:
          relationships[name1][name2] = 1
        else:
          relationships[name1][name2] += 1

对于出现在同一个段落中的人物,我们认为他们是关系紧密的,每同时出现一次,关系增加1.

保存到文件

with open("relationship.csv", "w", encoding='utf-8') as f:
    f.write("Source,Target,Weight\n")
    for name, edges in relationships.items():
      for v, w in edges.items():
        f.write(name + "," + v + "," + str(w) + "\n")

  with open("NameNode.csv", "w", encoding='utf-8') as f:
    f.write("ID,Label,Weight\n")
    for name, times in names.items():
      f.write(name + "," + name + "," + str(times) + "\n")
  • 文件1:人物关系表,包含首先出现的人物、之后出现的人物和一同出现次数
  • 文件2:人物比重表,包含该人物总体出现次数,出现次数越多,认为所占比重越大。

制作关系图表

使用 pyecharts 作图

def deal_graph():
  relationship_data = pd.read_csv('relationship.csv')
  namenode_data = pd.read_csv('NameNode.csv')
  relationship_data_list = relationship_data.values.tolist()
  namenode_data_list = namenode_data.values.tolist()

  nodes = []
  for node in namenode_data_list:
    if node[0] == "宝玉":
      node[2] = node[2]/3
    nodes.append({"name": node[0], "symbolSize": node[2]/30})
  links = []
  for link in relationship_data_list:
    links.append({"source": link[0], "target": link[1], "value": link[2]})

  g = (
    Graph()
    .add("", nodes, links, repulsion=8000)
    .set_global_opts(title_opts=opts.TitleOpts(title="红楼人物关系"))
  )
  return g

首先把两个文件读取成列表形式

对于“宝玉”,由于其占比过大,如果统一进行缩放,会导致其他人物的 node 过小,展示不美观,所以这里先做了一次缩放

最后得出的关系图

如何用Python来理一理红楼梦里的那些关系

所有代码已经上传至 Github

最后,我还准备了一份更加全面的红楼人物字典,可以在代码仓库中找到-“renwu_total”,感兴趣的小伙伴也可以尝试下,制作一个全人物的关系图。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Python 相关文章推荐
Python字符遍历的艺术
Sep 06 Python
Django imgareaselect手动剪切头像实现方法
May 26 Python
python reduce 函数使用详解
Dec 05 Python
Python实现的生成格雷码功能示例
Jan 24 Python
详解Pytorch 使用Pytorch拟合多项式(多项式回归)
May 24 Python
python numpy 按行归一化的实例
Jan 21 Python
用uWSGI和Nginx部署Flask项目的方法示例
May 05 Python
Python 求数组局部最大值的实例
Nov 26 Python
解决Tensorflow占用GPU显存问题
Feb 03 Python
Python提取视频中图片的示例(按帧、按秒)
Oct 22 Python
matplotlib之pyplot模块坐标轴标签设置使用(xlabel()、ylabel())
Feb 22 Python
Python制作运行进度条的实现效果(代码运行不无聊)
Feb 24 Python
django之自定义软删除Model的方法
Aug 14 #Python
python实现登录密码重置简易操作代码
Aug 14 #Python
python 定时器每天就执行一次的实现代码
Aug 14 #Python
Django 项目重命名的实现步骤解析
Aug 14 #Python
Django如何实现网站注册用户邮箱验证功能
Aug 14 #Python
python 叠加等边三角形的绘制的实现
Aug 14 #Python
Django为窗体加上防机器人的验证码功能过程解析
Aug 14 #Python
You might like
PHP的explode和implode的使用说明
2011/07/17 PHP
php写的带缓存数据功能的mysqli类
2012/09/06 PHP
php对象在内存中的存在形式分析
2015/02/03 PHP
PhpStorm 如何优雅的调试Hyperf的方法步骤
2019/11/24 PHP
关于JavaScript与HTML的交互事件
2013/04/12 Javascript
jquery 实现上下滚动效果示例代码
2013/08/09 Javascript
js 动态修改css文件的方法
2014/08/05 Javascript
深入理解JavaScript系列(36):设计模式之中介者模式详解
2015/03/04 Javascript
在浏览器中打开或关闭JavaScript的方法
2015/06/03 Javascript
jQuery简单实现验证邮箱格式
2015/07/15 Javascript
JavaScript实现基于十进制的四舍五入实例
2015/07/17 Javascript
js实现全国省份城市级联下拉菜单效果代码
2015/09/07 Javascript
javascript制作照片墙及制作过程中出现的问题
2016/04/04 Javascript
jquery删除table当前行的实例代码
2016/10/07 Javascript
详解JS异步加载的三种方式
2017/03/07 Javascript
NodeJs模拟登陆正方教务
2017/04/28 NodeJs
vue中重定向redirect:‘/index‘,不显示问题、跳转出错的完美解决
2020/09/28 Javascript
详细介绍Python语言中的按位运算符
2013/11/26 Python
搞笑的程序猿:看看你是哪种Python程序员
2015/06/12 Python
Python中matplotlib中文乱码解决办法
2017/05/12 Python
Python IDLE清空窗口的实例
2018/06/25 Python
Python脚本完成post接口测试的实例
2018/12/17 Python
python中时间转换datetime和pd.to_datetime详析
2019/08/11 Python
Python 使用 docopt 解析json参数文件过程讲解
2019/08/13 Python
Django+uni-app实现数据通信中的请求跨域的示例代码
2019/10/12 Python
python base64库给用户名或密码加密的流程
2020/01/02 Python
python文件读取失败怎么处理
2020/06/23 Python
林清轩官方网站:山茶花润肤油开创者
2016/10/26 全球购物
欧舒丹澳洲版:L’OCCITANE
2017/07/17 全球购物
项目经理的岗位职责
2013/11/23 职场文书
工作睡觉检讨书
2014/02/25 职场文书
毕业班联欢会主持词
2014/03/27 职场文书
2014年学校工作总结
2014/11/20 职场文书
领导参观欢迎词
2015/01/26 职场文书
python 命令行传参方法总结
2021/05/25 Python
HTML+JS实现在线朗读器
2022/02/15 Javascript