如何用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代码更快运行的5种方法
Jun 21 Python
Python中使用支持向量机SVM实践
Dec 27 Python
Python编程中NotImplementedError的使用方法
Apr 21 Python
python 3.6.4 安装配置方法图文教程
Sep 18 Python
python pcm音频添加头转成Wav格式文件的方法
Jan 09 Python
对Python中的条件判断、循环以及循环的终止方法详解
Feb 08 Python
如何运行.ipynb文件的图文讲解
Jun 27 Python
简单了解python高阶函数map/reduce
Jun 28 Python
Flask框架学习笔记之表单基础介绍与表单提交方式
Aug 12 Python
在keras中获取某一层上的feature map实例
Jan 24 Python
更新升级python和pip版本后不生效的问题解决
Apr 17 Python
浅谈Python3多线程之间的执行顺序问题
May 02 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 empty函数判断mysql表单是否为空
2010/04/12 PHP
php连接Access数据库错误及解决方法
2013/06/20 PHP
php实现12306余票查询、价格查询示例
2014/04/17 PHP
php单例模式实现方法分析
2015/03/14 PHP
PHP版本如何选择?应该使用哪个版本?
2015/05/13 PHP
PHP使用SWOOLE扩展实现定时同步 MySQL 数据
2017/04/09 PHP
php在windows环境下获得cpu内存实时使用率(推荐)
2018/02/08 PHP
validator验证控件使用代码
2010/11/23 Javascript
浅析Prototype的模板类 Template
2011/12/07 Javascript
html组件不可输入(只读)同时任何组件都有效
2013/04/01 Javascript
教你如何使用node.js制作代理服务器
2014/11/26 Javascript
JavaScript数据结构与算法之栈详解
2015/03/12 Javascript
Js+php实现异步拖拽上传文件
2015/06/23 Javascript
JS判断元素是否在数组内的实现代码
2016/03/30 Javascript
简单的分页代码js实现
2016/05/17 Javascript
关于Vue.js 2.0的Vuex 2.0 你需要更新的知识库
2016/11/30 Javascript
js实现图片左右滚动效果
2017/02/27 Javascript
解决Vue axios post请求,后台获取不到数据的问题方法
2018/08/11 Javascript
浅谈Angular 观察者模式理解
2018/11/01 Javascript
详解几十行代码实现一个vue的状态管理
2019/01/28 Javascript
Vue与React的区别和优势对比
2020/12/18 Vue.js
Python导出数据到Excel可读取的CSV文件的方法
2015/05/12 Python
Python中文分词工具之结巴分词用法实例总结【经典案例】
2017/04/15 Python
python实现微信每日一句自动发送给喜欢的人
2019/04/29 Python
python list数据等间隔抽取并新建list存储的例子
2019/11/27 Python
在 Windows 下搭建高效的 django 开发环境的详细教程
2020/07/27 Python
Python实现AES加密,解密的两种方法
2020/10/03 Python
Python命令行参数argv和argparse该如何使用
2021/02/08 Python
医学院学生的自我评价分享
2013/11/19 职场文书
教学质量评估实施方案
2014/03/17 职场文书
岗位说明书范文
2014/05/07 职场文书
四风问题民主生活会对照检查材料思想汇报
2014/09/27 职场文书
小学生差生评语
2014/12/29 职场文书
国家助学金感谢信
2015/01/21 职场文书
2015年党务公开工作总结
2015/05/19 职场文书
Python中使用tkFileDialog实现文件选择、保存和路径选择
2022/05/20 Python