??? 這次我們來制作《紅樓夢》各章節的分布情況:
源代碼:
import pandas as pd
import numpy as np
import matplotlib.pyplot as pltdf_hlm = pd.read_csv("hlm.txt", names=["hlm_texts"]).dropna()df_hlm = df_hlm[~df_hlm.hlm_texts.str.contains(r"第\d卷")].reset_index(drop=True)hui_mask = df_hlm.hlm_texts.str.match(r"第.+?回")
df_hui = pd.DataFrame(df_hlm.hlm_texts[hui_mask].str.split(' ').tolist(),columns=['Huiname', 'Firstname', 'Secondname'])df_hui['HuiNum'] = np.arange(1, len(df_hui) + 1)
df_hui['AllName'] = df_hui['Firstname'] + ',' + df_hui['Secondname']
df_hui['Start'] = hui_mask[hui_mask].index
df_hui['End'] = df_hui['Start'].shift(-1, fill_value=df_hlm.index[-1] + 1) - 1
df_hui['LineNum'] = df_hui['End'] - df_hui['Start']df_hui['Text'] = df_hui.apply(lambda row: ''.join(df_hlm.hlm_texts[row['Start'] + 1:row['End'] + 1]).replace('\u3000', ''), axis=1)
df_hui['ZiShu'] = df_hui['Text'].str.len()plt.rcParams.update({'font.sans-serif': 'SimHei','savefig.format': 'svg','axes.unicode_minus': False
})plt.figure(figsize=(10, 6))
scatter = plt.scatter(df_hui['LineNum'], df_hui['ZiShu'])
for num, row in df_hui.iterrows():plt.text(row['LineNum'] + 1, row['ZiShu'], row['HuiNum'])plt.xlabel("章節段落數", fontsize=12)
plt.ylabel("章節字數", fontsize=12)
plt.title('《紅樓夢》整本書各章節分布情況', fontsize=18)
plt.savefig('plot.svg')
plt.show()
??? 從生成的圖和代碼中我們都能看到各章節的分布情況和詞云無關,這是對于文本解讀的一種方式。繪圖前我們需要對文本進行一些基本處理。處理之前我們先看一下紅樓夢的目錄,這是傳統的章回體。章回體是中國古代長篇小說的一種敘述體式。其特點是將整部作品分成若干章節,稱為 “回” 或 “則”。每回都有相對獨立的情節,但又與前后回目緊密相連,共同構成一個完整的故事。每回的開頭和結尾往往有一些固定的格式,比如開頭常用 “話說”“且說” 等套語,結尾則多以 “欲知后事如何,且聽下回分解” 之類的話語來吸引讀者繼續閱讀。
?根據目標:制作紅樓夢各章節的分布情況。所以在處理時我們需要將每一回分開。
?
?讓我們來逐一解讀代碼:
(1)dropna()去除缺失值(NaN)
在 DataFrame
上使用時:
DataFrame.dropna(axis=0, how='any', thresh=None, subset=None, inplace=False)
在 Series
上使用時:
Series.dropna(axis=0, inplace=False)
axis
:指定刪除缺失值的方向,取值可以是0
或'index'
(默認值),表示按行刪除;取值為1
或'columns'
時,表示按列刪除。how
:指定刪除行或列的條件,取值可以是'any'
(默認值),表示只要該行或列中有一個缺失值就刪除;取值為'all'
時,表示只有當該行或列中的所有值都是缺失值時才刪除。thresh
:一個整數,指定保留行或列所需的非缺失值的最小數量。如果某行或列的非缺失值數量小于thresh
,則將其刪除。subset
:一個列標簽的列表,用于指定在哪些列中檢查缺失值。只有在這些列中存在缺失值的行或列才會被考慮刪除。inplace
:一個布爾值,默認為False
。如果設置為True
,則會直接在原對象上進行修改,不返回新的對象;如果設置為False
,則會返回一個新的對象,原對象保持不變。
補充:
Series
:一維的帶標簽數組。DataFrame
:二維的表格型數據結構,由多個Series
組成。
df_hlm = pd.read_csv("hlm.txt", names=["hlm_texts"]).dropna()
?讀取紅樓夢文本,命名為hlm_texts,去除空行
補充:這里的去除空行是一個預操作,在簡化文本數據的時候同時方便后續使用正則表達式提取卷、回信息,若存在空行容易導致匹配結果不準確。
?
(2)DataFrame
數據標簽:具有行索引(index
)和列索引(columns
),可以通過這些索引來訪問和操作數據。
DataFrame
對象可以通過 .
操作符加上列名來訪問該 DataFrame
中的某一列。如 df.Age
所以 df_hlm.hlm_texts
就是從 df_hlm
這個 DataFrame
中選取名為 hlm_texts
的列。
?
df_hlm = df_hlm[~df_hlm.hlm_texts.str.contains(r"第\d卷")].reset_index(drop=True)
?
?
?
?