使用Python探索四大名著【紅樓夢】人物之間的關係,簡直帥呆了

来源:https://www.cnblogs.com/hahaa/archive/2022/08/11/16576636.html
-Advertisement-
Play Games

《紅樓夢》作為我國四大名著之一,古典小說的巔峰之作,粉絲量極其龐大,而紅學也經久不衰。所以我們今天通過 Python 來探索下紅樓夢裡那千絲萬縷的人物關係,話不多說,開始整活! 一、準備工作 紅樓夢txt格式電子書一份 金陵十二釵+賈寶玉人物名稱列表 寶玉 nr 黛玉 nr 寶釵 nr 湘雲 nr ...


 

 


《紅樓夢》作為我國四大名著之一,古典小說的巔峰之作,粉絲量極其龐大,而紅學也經久不衰。所以我們今天通過 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()

# 更多視頻教程、電子書、源碼加君羊:279199867

 

 

接下來進行出場次數數據整理

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()

 

 

 

三、人物關係

1、數據處理

我們先將讀取到記憶體中的小說內容進行 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:人物比重表,包含該人物總體出現次數,出現次數越多,認為所占比重越大。

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 過小,展示不美觀,所以這裡先做了一次縮放

最後我們得到的人物關係圖如下

 

 


鐵子們,今天的分享就到這, 如果感覺文章內容不錯的話,記得關註+收藏讓更多的人看到!

給大家分享一套視頻,非常全面!

Python爬蟲:代碼總是學完就忘記?100個爬蟲實戰項目!讓你沉迷學習丨學以致用丨下一個Python大神就是你!

 

 

 


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • Java集合02 6.ArrayList ArrayList的註意事項: Permits all element , including null ,ArrayList 可以加入null ,並且可以加入多個 ArrayList是由數組來實現數據存儲的 ArrayList基本等同於Vector,除了A ...
  • 歡迎大家移步 我的博客 查看原文。 1. 前言 上機時遇到如下 C++ 代碼 ( C 代碼): //刪除帶頭結點的多項式單鏈表中繫數為 0 項 void DelZero(PolyNode *&L) { PolyNode *pre = L, *p = pre->next; while (p != NU ...
  • 基本類型 Rust 每個值都有其確切的數據類型,總的來說可以分為兩類:基本類型和複合類型。 基本類型意味著它們往往是一個最小化原子類型,無法解構為其它類型(一般意義上來說),由以下組成: 數值類型: 有符號整數 (i8, i16, i32, i64, isize)、 無符號整數 (u8, u16,  ...
  • ##網路協議 通過電腦網路可以使多台電腦實現連接,位於同一個網路中的電腦在進行連接和通信時需要遵守一定的規則,這就好比在道路中行駛的汽車一定要遵守交通規則一樣。在電腦網路中,這些連接和通信的規則被稱為網路通信協議,它對數據的傳輸格式、傳輸速率、傳輸步驟等做了統一規定,通信雙方必須同時遵守才能 ...
  • 《笨辦法學Python3 》免費下載地址 內容簡介 · · · · · · 本書是一本Python入門書籍,適合對電腦瞭解不多,沒有學過編程,但對編程感興趣的讀者學習使用。這本書以習題的方式引導讀者一步一步學習編程,從簡單的列印一直講到完整項目的實現,讓初學者從基礎的編程技術入手,最終體驗到軟體開 ...
  • 啥是函數式介面、它和JAVA中普通的介面有啥區別?函數式介面有啥用?如何在實際編碼中使用函數式介面?帶著這些問題,我們一起來認識下函數式介面的廬山真面目。 ...
  • 函數是基於功能或者邏輯進行聚合的可復用的代碼塊。將一些複雜的、冗長的代碼抽離封裝成多個代碼片段,即函數,有助於提高代碼邏輯的可讀性和可維護性。不同於Python,由於 Go lang是編譯型語言,編譯之後再運行,所以函數的定義順序無關痛癢。 函數聲明 在 Go lang里,函數聲明語法如下: fun ...
  • 《Python高手之路 第3版》|免費下載地址 作者簡介 · · · · · · Julien Danjou 具有12年從業經驗的自由軟體黑客。擁有多個開源社區的不同身份:Debian開發者、Freedesktop貢獻者、GNU Emacs提交者、awesome視窗管理器的創建者以及OpenStac ...
一周排行
    -Advertisement-
    Play Games
  • 經常看到有群友調侃“為什麼搞Java的總在學習JVM調優?那是因為Java爛!我們.NET就不需要搞這些!”真的是這樣嗎?今天我就用一個案例來分析一下。 昨天,一位學生問了我一個問題:他建了一個預設的ASP.NET Core Web API的項目,也就是那個WeatherForecast的預設項目模 ...
  • 很多軟體工程師都認為MD5是一種加密演算法,然而這種觀點是不對的。作為一個 1992 年第一次被公開的演算法,到今天為止已經被髮現了一些致命的漏洞。本文討論MD5在密碼保存方面的一些問題。 ...
  • Maven可以使我們在構建項目時需要用到很多第三方類jar包,如下一些常用jar包 而maven的出現可以讓我們避免手動導入jar包出現的某些問題,它可以自動下載那須所需要的jar包 我們只需要在創建的maven項目自動生成的pom.xml中輸入如下代碼 <dependencies> <!--ser ...
  • 來源:https://developer.aliyun.com/article/694020 非同步調用幾乎是處理高併發Web應用性能問題的萬金油,那麼什麼是“非同步調用”? “非同步調用”對應的是“同步調用”,同步調用指程式按照定義順序依次執行,每一行程式都必須等待上一行程式執行完成之後才能執行;非同步調 ...
  • 1.面向對象 面向對象編程是在面向過程編程的基礎上發展來的,它比面向過程編程具有更強的靈活性和擴展性,所以可以先瞭解下什麼是面向過程編程: 面向過程編程的核心是過程,就是分析出實現需求所需要的步驟,通過函數一步一步實現這些步驟,接著依次調用即可,再簡單理解就是程式 從上到下一步步執行,從頭到尾的解決 ...
  • 10瓶毒藥其中只有一瓶有毒至少需要幾隻老鼠可以找到有毒的那瓶 身似浮雲,心如飛絮,氣若游絲。 用二分查找和二進位位運算的思想都可以把死亡的老鼠降到最低。 其中,二進位位運算就是每一隻老鼠代表一個二進位0或1,0就代表老鼠存活,1代表老鼠死亡;根據數學運算 23 = 8、24 = 16,那麼至少需要四 ...
  • 一、Kafka存在哪些方面的優勢 1. 多生產者 可以無縫地支持多個生產者,不管客戶端在使用單個主題還是多個主題。 2. 多消費者 支持多個消費者從一個單獨的消息流上讀取數據,而且消費者之間互不影響。 3. 基於磁碟的數據存儲 支持消費者非實時地讀取消息,由於消息被提交到磁碟,根據設置的規則進行保存 ...
  • 大家好,我是陶朱公Boy。 前言 上一篇文章《關於狀態機的技術選型,最後一個真心好》我跟大家聊了一下關於”狀態機“的話題。從眾多技術選型中我也推薦了一款阿裡開源的狀態機—“cola-statemachine”。 於是就有小伙伴私信我,自己項目也考慮引入這款狀態機,但網上資料實在太少,能不能系統的介紹 ...
  • 使用腳本自動跑實驗(Ubuntu),將實驗結果記錄在文件中,併在實驗結束之後將結果通過郵件發送到郵箱,最後在windows端自動解析成excel表格。 ...
  • 話說在前面,我不是小黑子~ 我是超級大黑子😏 表弟大周末的跑來我家,沒事幹天天騷擾我,搞得我都不能跟小姐姐好好聊天了,於是為了打發表弟,我決定用Python做一個小游戲來消耗一下他的精力,我思來想去,決定把他變成小黑子,於是做了一個坤坤打籃球的游戲,沒想到他還挺愛玩的~ 終於解放了,於是我把游戲寫 ...