如何用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中使用pyhook实现键盘监控的例子
Jul 18 Python
Python之PyUnit单元测试实例
Oct 11 Python
Apache如何部署django项目
May 21 Python
查看python下OpenCV版本的方法
Aug 03 Python
python树莓派红外反射传感器
Jan 21 Python
Python操作MySQL数据库的两种方式实例分析【pymysql和pandas】
Mar 18 Python
python excel转换csv代码实例
Aug 26 Python
Python 类方法和实例方法(@classmethod),静态方法(@staticmethod)原理与用法分析
Sep 20 Python
python super的使用方法及实例详解
Sep 25 Python
python GUI编程(Tkinter) 创建子窗口及在窗口上用图片绘图实例
Mar 04 Python
浅谈tensorflow 中的图片读取和裁剪方式
Jun 30 Python
Python实现科学占卜 让视频自动打码
Apr 09 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 动态多文件上传
2009/01/18 PHP
PHP中把有符号整型转换为无符号整型方法
2015/05/27 PHP
joomla数据库操作示例代码
2016/01/06 PHP
360搜索引擎自动收录php改写方案
2018/04/28 PHP
javascript getElementsByName()的用法说明
2009/07/31 Javascript
js 键盘记录实现(兼容FireFox和IE)
2010/02/07 Javascript
关于jQuery中.attr()和.prop()的问题探讨
2013/09/06 Javascript
javascript中的nextSibling使用陷(da)阱(keng)
2014/05/05 Javascript
JS实现拖拽的方法分析
2016/12/20 Javascript
HTML的select控件美化
2017/03/27 Javascript
angular中使用Socket.io实例代码
2017/06/03 Javascript
node使用Koa2搭建web项目的方法
2017/10/17 Javascript
JS常用的几种数组遍历方式以及性能分析对比实例详解
2018/04/11 Javascript
150行代码带你实现微信小程序中的数据侦听
2019/05/17 Javascript
[01:48]帕吉至宝加入游戏,遗迹战场现“千劫神屠”
2018/04/07 DOTA
Python编程对列表中字典元素进行排序的方法详解
2017/05/26 Python
[原创]windows下Anaconda的安装与配置正解(Anaconda入门教程)
2018/04/05 Python
解决python3 json数据包含中文的读写问题
2018/05/10 Python
Python 输出时去掉列表元组外面的方括号与圆括号的方法
2018/12/24 Python
Python魔法方法详解
2019/02/13 Python
Django实现发送邮件功能
2019/07/18 Python
python爬虫 基于requests模块的get请求实现详解
2019/08/20 Python
python实现通过flask和前端进行数据收发
2019/08/22 Python
在python中计算ssim的方法(与Matlab结果一致)
2019/12/19 Python
浅谈tensorflow中张量的提取值和赋值
2020/01/19 Python
校领导推荐信
2013/11/01 职场文书
总经理办公室主任岗位职责
2013/11/12 职场文书
房地产销售员的自我评价分享
2013/12/04 职场文书
政府门卫岗位职责
2014/04/29 职场文书
机械专业求职信
2014/05/25 职场文书
党的群众路线教育实践活动对照检查剖析材料
2014/10/09 职场文书
道德模范事迹材料
2014/12/20 职场文书
单独二胎证明
2015/06/24 职场文书
医院见习总结
2015/06/24 职场文书
小学体育组工作总结2015
2015/07/21 职场文书
html+css实现赛博朋克风格按钮
2021/05/26 HTML / CSS