Python探索《红楼梦》儒家关系!震惊!
《红楼梦》是中国古典小说的巅峰之作。太多人沉迷其中,对红色的研究也是永恒的。当然,今天我们不是来回顾小说的,而是利用Python来探讨人物与红楼梦中人物密不可分的关系。
开始~
资料准备
- 红楼梦电子书txt
- 金陵十二钗+贾宝玉与人物名单
宝玉 nr 黛玉 nr 宝钗 nr 湘云 nr 凤姐 nr 李纨 nr 元春 nr 迎春 nr 探春 nr 惜春 nr 妙玉 nr 巧姐 nr 秦氏 nr
此子词表用于本片段如下number是人名的意思
出现次数人物
先看小说
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分词处理将上面我们自定义的字典加载到jieba中通过load_userdict库
下一步是进行分词处理
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工具来处理分词,会返回每个分词的词性。
判断完成后,只保留符合要求且在我们提供的词典列表中的分词。
每出现一个人就加一,方便后面画关系图时确定人物结的大小。
对于我们自己字典中存在的人名,将其存储在临时变量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
先将两个文件读入内存
对于“宝玉”来说,由于其比例太大,如果均匀调整比例,就会导致其他人物节点太小,显示不美观。 ,所以我们先放大
最后得到的人物关系图如下
来源Python技术,白森江
版权声明
本文仅代表作者观点,不代表Code前端网立场。
本文系作者Code前端网发表,如需转载,请注明页面地址。
发表评论:
◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。