震惊!用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.read()接下来进行出场次数数据整理;
honglou = honglou.replace("\n", " ")
honglou_new = honglou.split(" ")
renwu_list = [宝玉, 黛玉, 宝钗, 湘云, 凤姐, 李纨, 元春, 迎春, 探春, 惜春, 妙玉, 巧姐, 秦氏]
renwu = pd.DataFrame(data=renwu_list, columns=[姓名])
renwu[出现次数] = renwu.apply(lambda x: len([k for k in honglou_new if x[u姓名] in k]), axis=1)
renwu.to_csv(renwu.csv, index=False, sep=,)
renwu.sort_values(出现次数, ascending=False, inplace=True)
attr = renwu[姓名][0:12]
v1 = renwu[出现次数][0:12]这样我们就得到了 attr 和 v1 两个数据,内容如下:

下面就可以通过 pyecharts 来绘制柱状图了;
bar = (
Bar()
.add_xaxis(attr.tolist())
.add_yaxis("上镜次数",索红 v1.tolist())
.set_global_opts(title_opts=opts.TitleOpts(title="红楼梦上镜13人"))
)
bar.render_notebook()
数据处理
我们先将读取到内存中的小说内容进行 jieba 分词处理;
import jieba
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()]通过 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首先把两个文件通过 pandas 读取到内存当中。
对于“宝玉”,由于其占比过大,如果统一进行缩放,会导致其他人物的 node 过小,展示不美观,所以这里先做了一次缩放。
最后我们得到的人物关系图如下:

相关文章
电脑关机提示异常错误,你需要知道的一切!(解决电脑关机异常错误问题,避免数据丢失与系统损坏)
摘要:在日常使用电脑的过程中,我们有时会遇到电脑关机时出现异常错误的情况。这种问题不仅会导致数据丢失和系统损坏,还会给我们带来诸多困扰。本文将针对电脑关机提示异常错误问题进行详细介绍,并...2025-11-04KD-65X9300E超高清电视的功能和性能如何?(一台令人惊叹的超高清电视,带来绝佳的观影体验)
摘要:作为科技领域的一个重要成果,电视机在不断地更新换代,最近推出的KD-65X9300E超高清电视备受关注。这款电视采用了最先进的技术,具有出色的画质和功能。本文将详细介绍KD-65X...2025-11-04- 摘要:随着科技的不断进步和人们生活水平的提高,智能交通方式成为了现代社会发展的重要方向。而XE680作为一款全新的智能交通工具,将为人们带来全新的出行体验和智能化交通管理。1...2025-11-04
共享文件夹的隐藏技巧(保护隐私、提升安全,一起来学习隐藏共享文件夹的方法吧!)
摘要:在日常工作和生活中,我们经常需要共享文件夹以便与他人协作。然而,有时候我们希望将某些文件夹隐藏起来,以保护隐私或增强安全性。本文将介绍一些方法,让你学会如何隐藏共享文件夹,让你的文...2025-11-04电脑主题安装密码错误的解决方法(忘记或输入错误密码时如何解决电脑主题安装问题)
摘要:在进行电脑主题安装过程中,有时候我们会遇到密码错误的问题。这可能是因为我们忘记了密码,或者是输入了错误的密码。无论是哪种情况,这都会导致我们无法正常地安装所需的电脑主题。为了帮助大...2025-11-04将PDF转换为Word(解密PDF到Word的转换技巧,提高办公效率)
摘要:在日常工作和学习中,我们经常会遇到需要将PDF文件转换成可编辑的Word文档的需求。然而,很多人却不清楚如何进行高效的PDF转Word操作。本文将介绍几种简便快捷的方法,帮助您快速...2025-11-04

最新评论