更多优质内容
请关注公众号

Python数据分析小案例——红楼梦文本分析(一) 文本预处理-张柏沛IT博客

正文内容

Python数据分析小案例——红楼梦文本分析(一) 文本预处理

栏目:Python 系列:Python数据分析系列 发布时间:2019-12-20 15:59 浏览量:5476

本文开始介绍一个简单的数据分析案例,分析红楼梦文本,本文主要内容是将红楼梦文本按照章节获取每一回的标题,字数,段落数并保存到csv中方便后续数据分析

 

红楼梦小说文本可以在这里下载

链接:https://pan.baidu.com/s/1WEmunBN_Wo75EZd1cK6_lA 
提取码:3xco 

 

接下来直接上代码

 

import pandas as pd
import numpy as np

with open("./hlm/red.txt",encoding="utf-8") as f:
    content = f.readlines()

content = pd.DataFrame(content)  #将行转为df,这个df只有一列
content.columns = ["content"]    #取列名为content,以防content[0]会有歧义,不知道是表示第一列还是第一行

print(content)

#查看是否有为空的行
print(np.sum(content.isnull()))

#删除 第x卷 这样的行
has_juan = content["content"].str.contains(r"^第.+?卷")   #返回 [True,False,....,False]
# print(content[has_juan])
index_has_juan = has_juan.index[has_juan.values==True]   #或者has_juan[has_juan==True].index
# print(content.drop(index_has_juan))

content = content.drop(index_has_juan)
content = content.reset_index(drop=True)   #重新设定index

#或者这样做也可以
has_juan = content["content"].str.contains(r"^第.+?卷")
content = content[~has_juan].reset_index(drop=True)   #content[has_juan] 就是有卷的行,~取反 是没有第x卷的行

print(content)
content.to_csv("./hlm_cont.csv",index=False)

#获取每一回的标题
has_hui = content["content"].str.match(r"^第.+回")   #match和contains都一样
cont_with_hui = content[has_hui]["content"].str.strip("\r\n").str.split(" ").reset_index(drop=True) #获取回的行并且将里面的内容按照空格分开,这里返回的是一个Series
print(cont_with_hui)

df_hui = pd.DataFrame(list(cont_with_hui),columns=["chapterNum","leftName","rightName"])    #这里必须将cont_with_hui从series转为list,否则得到的是一个空df
print(df_hui)

df_hui["fullName"] = df_hui['leftName']+pd.Series([" " for i in range(len(df_hui))])+df_hui['rightName']
print(df_hui)

#获取每一回的段落数和字数

#段落数 = 每回最后一段的行号-回标题所在的行号
df_hui['parag_start'] = has_hui[has_hui==True].index   #回标题所在行号
parag_end = df_hui['parag_start'][1:len(df_hui['parag_start'])]-1  #每回最后一行行号
parag_end = parag_end.reset_index(drop=True)  #此时parag_end只有119个元素,还缺最后一回的最后一段的行号
parag_end[len(parag_end)] = content.index[-1]
df_hui['parag_end'] = parag_end

df_hui['parag_num'] = df_hui['parag_end'] - df_hui['parag_start']  #段落数

#每回的字数 = 每回的段落所在的行的内容的长度求和(文字内容不包括\r\n,回标题字数不算在内)
str_len = content['content'].apply(lambda x:len(x.strip("\r\n").replace(" ","")))

str_len_hui = pd.Series(np.arange(len(df_hui)))   #这里str_len_hui不能生成一个空Series,否则下面str_len_hui[i]=xxx会报错
# print(str_len_hui)
for i in range(len(df_hui)):
    #获取每回的开始段和结束段的index
    start = df_hui['parag_start'][i]+1
    end = df_hui['parag_end'][i]

    #获取每回所在的行
    hang_each_hui = str_len[start:(end+1)]
    str_len_hui[i] = hang_each_hui.sum()    #对每回对应的所有行的字数求合,就是每回的字数

print(str_len_hui)

df_hui['str_len']= str_len_hui


#将红楼梦回的数据存为csv
df_hui.to_csv("./hlm_chapter_info.csv",index=False)

 

得到的csv内容如下:

红楼梦章节文本处理

 

得到了每一章的字数和段落数之后,可以根据绘出字数和段落数的散点图和折线图,代码实现如下:

# 根据红楼梦每一回的数据做每回段落数和字数的散点图,并在每个点上标记是第几回
import matplotlib.pyplot as plt
import pandas as pd
import numpy as np

plt.rcParams['font.sans-serif']=['SimHei']  #正常显示中文
plt.rcParams['axes.unicode_minus'] = False  #正常显示负号

df_hui = pd.read_csv("./hlm_chapter_info.csv")
print(df_hui)

fig = plt.figure(figsize=(16,16))
fig.suptitle("《红楼梦》120回")  #四个图的总标题,plt.title()是设置子标题

plt.subplot(221)
plt.scatter(df_hui['parag_num'],df_hui['str_len'])
plt.xlabel("每回段落数")
plt.ylabel("每回字数")
for i in range(len(df_hui)):
    plt.text(df_hui['parag_num'][i],df_hui['str_len'][i],df_hui['chapterNum'][i],size=7)  #给每个点做上文字说明,前两参是文字说明的位置,x,y;第三参是文字说明的内容;size是字体大小

plt.subplot(222)
plt.scatter(df_hui['parag_num'],df_hui['str_len'])
plt.xlabel("每回段落数")
plt.ylabel("每回字数")
for i in range(len(df_hui)):
    plt.text(df_hui['parag_num'][i]+1,df_hui['str_len'][i],i+1)

#绘制点线图,横坐标是章节数,纵坐标是章节字数和章节段落数
plt.subplot(223)
plt.plot(df_hui.index+1,df_hui['parag_num'],"ro-")
plt.hlines(np.mean(df_hui['parag_num']),-5,125)    #画一条水平线,显示段落数的平均值
plt.xlim((-5,125))  #限制x轴视图范围
plt.xlabel("章节")
plt.ylabel("章节段落数")

plt.subplot(224)
plt.plot(df_hui.index+1,df_hui['str_len'],"ro-")  #r红色,o控制点的样式,-控制线的样式
plt.hlines(np.mean(df_hui['str_len']),-5,125)
plt.xlim((-5,125))
plt.xlabel("章节")
plt.ylabel("章节字数")

plt.savefig("hlm1.png")
plt.show()

 

得到的图像如下图所示(图片较大,可以点击图片查看放大的图片):

红楼梦章节字数和段落数散点图和折线图

 

 




更多内容请关注微信公众号
zbpblog微信公众号

如果您需要转载,可以点击下方按钮可以进行复制粘贴;本站博客文章为原创,请转载时注明以下信息

张柏沛IT技术博客 > Python数据分析小案例——红楼梦文本分析(一) 文本预处理

热门推荐
推荐新闻