代码注解 |《数据分析唐诗三百首》
摘要:本文介绍了分析唐诗三百首数据的基本流程。首先,对数据进行了预处理。其次,利用玫瑰图分析了唐诗三百首体裁构成。接着,利用桑基图找出体裁全能型创作选手。然后,拟合诗人寿命与作品出产量的关系。最后总结并给出建议。
需要说明的是,本文只介绍数据分析代码,更偏技术,相关内容的深入分析见文章《我用数据分析了唐诗三百首,发现最秀的竟然不是李白?》。
01 数据预处理
出于数据缺漏、录入等原因,数据预处理必不可少。如下代码所示,首先,利用pandas读取csv数据文件,接着对缺漏的数据进行填充,这里利用其他诗人的产量均值填充遗漏的诗人产量数据。然后,利用drop_duplicates()方法进行去重,保留第一次出现的重复值。其它的数据处理在后续相应部分按照分析需要进行。import pandas as pd
import collections,re,jieba,wordcloud,requests,folium,webbrowser,random
import pyecharts.options as opts
from pyecharts.charts import Sankey,Pie
import seaborn as sns
from matplotlib import pyplot as plt
from matplotlib import font_manager as fm
import numpy as np
from PIL import Image
from 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)
# 玫瑰图:唐诗体裁构成
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')
执行上述代码得到如下所示玫瑰图,可以看到唐诗三百首里出现次数最多的体裁是五言律诗,最少的是七言古诗。
# 桑基图:边-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')
执行上述代码得到下图所示桑基图,可以看到在七个唐诗体裁中,李白、杜甫等能创作,不愧是家喻户晓的“大李杜”,可谓全能型创作选手。
李、杜之后还有白居易、李商隐、王维、岑参和韦应物,他们的作品体裁也较为丰富。
散点拟合图利用的是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()
执行上述代码,得到如下拟合图。可以看到,诗人寿命对作品产量具有正向促进作用,平均寿命的增加会带来平均产量的增加。
综上,本文介绍了数据分析唐诗三百首的基本步骤,以及玫瑰图、桑基图和散点拟合图的代码实现。需要注意以下几点:
第一,数据分析之前数据预处理不可忽略,例如,去重、缺漏值处理等等。
第二,调用第三方库画图时,要注意了解数据接口形式。
第三,有些中文字体无法显示,注意在相关参数中配置本地字体文件。
数据 | YaJie
文章 | Yajie、璇璇璇璇子
编辑 | 璇璇璇璇子
1.网易音乐里有哪些打动你的评论?110万+条数据告诉你答案
2.我爬了淘宝5000+口红商品数据,差点比女朋友更懂口红?
3.给自己买或者送别人什么口红好呢?4353条口红数据帮你挑选品牌与色号
4.分析完13067条数据,我才发现上海有这么多好吃的地儿!
这是个有趣的公众号
只差个有趣的你
扫码关注Giao数据
一起用数据看生活