查看原文
其他

代码注解 |《数据分析唐诗三百首》

想读诗的小Giao Giao数据 2022-03-19

摘要:本文介绍了分析唐诗三百首数据的基本流程。首先,对数据进行了预处理。其次,利用玫瑰图分析了唐诗三百首体裁构成。接着,利用桑基图找出体裁全能型创作选手。然后,拟合诗人寿命与作品出产量的关系。最后总结并给出建议。


很多时候,数据获取只是第一步,如何利用现有的数据挖掘信息,深入的了解数据对象更为重要。在利用爬虫获取古诗文网唐诗三百首数据后,今天我们来探讨一下如何利用python对唐诗数据进行预处理、分析和可视化。

需要说明的是,本文只介绍数据分析代码,更偏技术,相关内容的深入分析见文章《我用数据分析了唐诗三百首,发现最秀的竟然不是李白?》。


01 数据预处理

出于数据缺漏、录入等原因,数据预处理必不可少。如下代码所示,首先,利用pandas读取csv数据文件,接着对缺漏的数据进行填充,这里利用其他诗人的产量均值填充遗漏的诗人产量数据。然后,利用drop_duplicates()方法进行去重,保留第一次出现的重复值。其它的数据处理在后续相应部分按照分析需要进行。
import pandas as pdimport collections,re,jieba,wordcloud,requests,folium,webbrowser,randomimport pyecharts.options as optsfrom pyecharts.charts import Sankey,Pieimport seaborn as snsfrom matplotlib import pyplot as pltfrom matplotlib import font_manager as fmimport numpy as npfrom PIL import Imagefrom folium.plugins import HeatMap
class POEM_analysis():
def __init__(self):        # 读取数据 self.data = pd.read_csv('POEM_info.csv')        # 缺失值处理 self.data.fillna(value={'amount':round(self.data['amount'].mean(),2)},inplace=True) # 去重 self.data.drop_duplicates(keep='first',inplace=True) # 查看数据结构 print(self.data.shape)

02 玫瑰图:唐诗三百首体裁构成
画玫瑰图利用的是大名鼎鼎的pyecharts库中的Pie这个类。在利用各类数据分析工具进行分析之前,最需要关注的就是分析工具的数据接口,即工具支持什么样的数据排列形式(列表、数组、元组还是字典等)。这里的Pie支持的是数组。这一部分分析思路为:首先,利用collections里面的Counter类进行计数,接着将体裁名和对应的值打包添加至大列表中。然后利用Pie配置相应参数进行可视化。具体见如下代码注解:
    # 玫瑰图:唐诗体裁构成 def type_rose(self):        # 统计频次 title_count = collections.Counter(self.data['type']) pair_lst = []        color_lst = ['#FAE927','#E9E416','#C9DA36','#9ECB3C','#6DBC49','#37B44E','#3DBA78']        # 打包统计的键值对为数组 for item in zip(dict(title_count).keys(),dict(title_count).values()): pair_lst.append(list(item))        # Pie实例化,配置参数 pie = Pie(init_opts=opts.InitOpts(width='800px', height='800px'))        # 上色 pie.set_colors(colors=color_lst)        # 数据接入,调参 pie.add("", pair_lst, radius=[40, 100], rosetype='area') # 关闭图例 pie.set_global_opts(legend_opts=opts.LegendOpts(is_show=False)) # 标签设置 pie.set_series_opts(label_opts=opts.LabelOpts(position='inside', font_size=8, font_style='italic',                                                      font_family='Microsoft YaHei', formatter='{b}:{c}')) pie.render(r'C:\Users\DELL\Desktop\数据分析\项目4--唐诗三百首\原始图片\rose_bar.html')

执行上述代码得到如下所示玫瑰图,可以看到唐诗三百首里出现次数最多的体裁是五言律诗,最少的是七言古诗。

03 桑基图:体裁通吃的全能型选手画桑基图最主要的准备工作也是在数据接口这一块。首先,要定义节点和联系,特别是节点的获取要用unique()方法得到不重复的节点名称。“联系”links要按照“source-target-value”的形式储存为字典,再放到大列表中。接着,配置Sankey的参数对桑基图进行画图和优化。其中,curve和opacity分别控制流量带的曲率和图形颜色的透明度。具体代码如下:
# 桑基图:边-type体裁,流量-作者出现次数,节点-作者 def sankey_plot(self):        # 数据可以是原来的数组切片,也可以重新打包形成特定数组 type_lst = self.data['type'].tolist() author_lst = self.data['author'].tolist() output_lst = self.data['amount'].tolist() apr_lst = [1 for i in range(320)] df_lst = [[type_lst[i],author_lst[i],apr_lst[i],output_lst[i]] for i in range(320)] df = pd.DataFrame(df_lst,columns=['type','author','appear','output']) print('df.shape:',df.shape)        # 去掉产量小于350的诗人数据 labels = [] for i,item in enumerate(df.values): if item.tolist()[3] <= 350: labels.append(i) df.drop(labels=labels,inplace=True) df.reset_index(drop=True,inplace=True) print('删除后shape:',df.shape) # 定义节点 nodes = [] for item in ['type','author']: values = df[item].unique() for value in values: dct = {} dct['name'] = value nodes.append(dct) # 定义link:source-target-value links = [] for item in df.values: dct = {} dct['source'] = item[0] dct['target'] = item[1] dct['value'] = item[2] links.append(dct) print('links长度:',len(links)) # 配置桑基图参数        sk = Sankey(init_opts=opts.InitOpts(width='800px', height='900px')) # color = ['#aaa','#0EFFFF','#FF100E','#5C52FF','#FFFF16','#f71b1b','#aaa'] # sk.set_colors(color)        # 接入数据,配置节点、流量带和标签等参数 sk.add(series_name='',nodes=nodes,links=links, itemstyle_opts=opts.ItemStyleOpts(border_width=1, border_color='#F4F8F4'), linestyle_opt=opts.LineStyleOpts(color='target', curve=0.7, opacity=0.6,type_='dotted'), label_opts=opts.LabelOpts(position='right',interval=1)) #orient='vertical' sk.render(r'C:\Users\DELL\Desktop\数据分析\项目4--唐诗三百首\原始图片\sankey.html')

执行上述代码得到下图所示桑基图,可以看到在七个唐诗体裁中,李白、杜甫等能创作,不愧是家喻户晓的“大李杜”,可谓全能型创作选手。

李、杜之后还有白易、李商隐、王维、岑参和韦应物,他们的作品体裁也较为丰富。

04 散点拟合图:诗人寿命与产量

散点拟合图利用的是seaborn的regplot。相对于散点图,regplot的好处是会直接给出拟合曲线和置信区间。

数据接口还是数组的形式,这里要注意的是有时候坐标轴标签会出现中文显示成框框的情况,因此要在参数里配置字体文件予以解决。

下面代码较长,主要还是在于需要用的数据清洗和准备部分:

    # 散点拟合图:诗人寿命与产量 def reg_plt(self): # 去掉全部缺漏的数据 self.data.dropna(inplace=True)        self.data.reset_index(drop=True,inplace=True) chinesefont = fm.FontProperties(fname='C:\Windows\Fonts\simsun.ttc')        # 生成所需数组df,其中columns为'birthday','deathday','output'。 # ...        # 节约篇幅,这一部分省略,通过切片或者重新生成均可。 # 计算寿命 temp1 = [] temp2 = [] for val in df.values: birth = val.tolist()[0] death = val.tolist()[1] lifespan = round(death-birth) temp1.append(lifespan) if lifespan >= 10: temp2.append(lifespan) lifespan_processed = [] for v in temp1: if v <= 10: v = np.array(temp2).mean() lifespan_processed.append(v)        # 将寿命添加至df最右一列 df['lifespan'] = lifespan_processed        # 配置拟合图参数 sns.regplot(x='lifespan', y='output', data=df,color='#6DE1CB') plt.xlabel('寿命', fontproperties=chinesefont, fontsize=10) plt.ylabel('产量', fontproperties=chinesefont, fontsize=10) plt.tight_layout() plt.savefig(r'C:\Users\DELL\Desktop\数据分析\项目4--唐诗三百首\原始图片\reg.png',dpi=900) plt.show()

执行上述代码,得到如下拟合图。可以看到,诗人寿命对作品产量具有正向促进作用,平均寿命的增加会带来平均产量的增加。

05 总结

综上,本文介绍了数据分析唐诗三百首的基本步骤,以及玫瑰图、桑基图和散点拟合图的代码实现。需要注意以下几点:


第一,数据分析之前数据预处理不可忽略,例如,去重、缺漏值处理等等。


第二,调用第三方库画图时,要注意了解数据接口形式。


第三,有些中文字体无法显示,注意在相关参数中配置本地字体文件。


数据 | YaJie 

文章 | Yajie、璇璇璇璇子

编辑 | 璇璇璇璇子



1.网易音乐里有哪些打动你的评论?110万+条数据告诉你答案

2.我爬了淘宝5000+口红商品数据,差点比女朋友更懂口红?

3.给自己买或者送别人什么口红好呢?4353条口红数据帮你挑选品牌与色号

4.分析完13067条数据,我才发现上海有这么多好吃的地儿!

5.我用数据分析了唐诗三百首,发现最秀的竟然不是李白?

这是个有趣的公众号

只差个有趣的你

扫码关注Giao数据

一起用数据看生活


您可能也对以下帖子感兴趣

文章有问题?点此查看未经处理的缓存