Python高能绘图 | 解锁分析唐诗新技能
The following article is from Giao数据 Author 想读诗的小Giao
爬虫俱乐部云端课程来袭!
爬虫俱乐部将于2020年8月25日至28日在线上举行Stata数据分析法律与制度专题训练营,主要是为了让学员掌握Stata软件进阶操作,涉及内容包括基本字符串函数及其应用、正则表达式、法律与制度数据网络爬虫技巧、判案文书的文本分析等技术。详情请参考《8月Stata数据分析法律与制度专场来啦!》
另外,爬虫俱乐部于2020年7月在线上举办的Stata与Python编程技术训练营已圆满结束。应广大学员需求,我们的课程现已在腾讯课堂双双上线,且继续提供答疑服务。现在关注公众号并在朋友圈转发推文《来腾讯课堂学Stata和Python啦!》,即可获得600元课程优惠券,集赞50个再领200元课程优惠劵!(截图发至本公众号后台领取)原价2400元的课程,现在只要1600元!
摘要:本文介绍了分析唐诗三百首数据的基本流程。首先,对数据进行了预处理。其次,利用玫瑰图分析了唐诗三百首体裁构成。接着,利用桑基图找出体裁全能型创作选手。然后,拟合诗人寿命与作品出产量的关系。最后总结并给出建议。
需要说明的是,本文只介绍数据分析代码,更偏技术,相关内容的深入分析见文章《我用数据分析了唐诗三百首,发现最秀的竟然不是李白?》。
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()
执行上述代码,得到如下拟合图。可以看到,诗人寿命对作品产量具有正向促进作用,平均寿命的增加会带来平均产量的增加。
综上,本文介绍了数据分析唐诗三百首的基本步骤,以及玫瑰图、桑基图和散点拟合图的代码实现。需要注意以下几点:
第一,数据分析之前数据预处理不可忽略,例如,去重、缺漏值处理等等。
第二,调用第三方库画图时,要注意了解数据接口形式。
第三,有些中文字体无法显示,注意在相关参数中配置本地字体文件。
对我们的推文累计打赏超过1000元,我们即可给您开具发票,发票类别为“咨询费”。用心做事,不负您的支持!
往期推文推荐
用WordStat看中国日报新闻(二)
一招轻松合并文件——openall命令介绍
爬虫俱乐部平安经一个函数实现PDF文档合并与拆分补全股票代码位数的一百种姿势高校经管类核心期刊发文排行榜|2010-2019
PDF图片提取PDF文档转换成图片PyMuPDF提取文本信息大数据视角下的大学录取分数排行集成学习介绍之二——Boosting算法关于我们
微信公众号“Stata and Python数据分析”分享实用的stata、python等软件的数据处理知识,欢迎转载、打赏。我们是由李春涛教授领导下的研究生及本科生组成的大数据处理和分析团队。
此外,欢迎大家踊跃投稿,介绍一些关于stata和python的数据处理和分析技巧。投稿邮箱:statatraining@163.com投稿要求:1)必须原创,禁止抄袭;
2)必须准确,详细,有例子,有截图;
注意事项:
1)所有投稿都会经过本公众号运营团队成员的审核,审核通过才可录用,一经录用,会在该推文里为作者署名,并有赏金分成。
2)邮件请注明投稿,邮件名称为“投稿+推文名称”。
3)应广大读者要求,现开通有偿问答服务,如果大家遇到有关数据处理、分析等问题,可以在公众号中提出,只需支付少量赏金,我们会在后期的推文里给予解答。