数据流
- 数据抓取
- 数据处理,比如清洗,脱敏等
- 数据可视化 ,使用工具库生成图例
可视化
matplotlib
- matplotlib简介
Python 2D
绘图库- 通过 Matplotlib 就可以方便地制作折线图、柱状图、散点图等各种高质量的数据图
- 常用函数或方法指引
matplotlib.pyplot.plot
生成折线图legend
图例time, xlabel,ylabel,xticks,yticks
设置坐标subplot
创建子图pie
创建饼图bar barh
柱状图scatter
散点图contour contourf
等高线plot_surface (Axes3D)
绘制3D图形figure
图形配置方法
pygal
- 简介
- 简易数据图库,以面向对象方式创建各种数据图
- 生成多种格式数据图,如PNG,SVG等,也可生成xml etree,html表格
- pygal生成数据图
- 创建 Pygal 数据图对象
- 比如柱状图使用 pygal.Bar 类,饼图使用 pygal.Pie 类,折线图使用 pygal.Line 类,等等
- 调用数据图对象的 add() 方法添加数据
- 调用 Config 对象的属性配置数据图
- 调用数据图对象的 render_to_xxx() 方法将数据图渲染到指定的输出节点
- 此处的输出节点可以是 PNG 图片、SVG 文件,也可以是其他节点
- 常用类
pygal.Line
折线图类pygal.HorizontalBar
水平柱状图类pygal.HorizontalLine
水平拆线图类pygal.StackedBar
叠加柱状图类pygal.StackedBar
叠加折线图类pygal.Pie
饼图类pygal.Dot
点图类pygal.Gauge
仪表图类pygal.Radar
雷达图类 多维度展示数据
数据处理
csv
- csv数据
- 本质是一种文本存储的表格数据
- 每行代表一行数据,每个数据以逗号隔开
- csv模块读取csv文件
- 通常第一行是表头
- csv模块读取csv文件流程
- 创建csv模块的读取器
- 循环调用 csv 读取器reader函数的返回可迭代对象 next() 方法逐行读取 csv 文件内容
- 应用场景
- 技巧 使用open会隐式使用系统编码方式
- 数据可视化,首先可能要处理不同格式(比如 csv、JSON)的数据
- 查模块文档
python -m pydoc csv
pyton -m pydoc -b
json
- 使用json模块的
load()
函数加载 JSON
数据即可
数据抓取
- request库和re模块
- 流程(数据抓取,清洗,展示)
- request 构建请求体,发出请求
- re 构建正则对象,使用正则匹配源
- re 模块
compile(pattern, flags=0)
编译正则表达式,返回一个正则对象findall(pattern, string,flag=0)
返回一个非重复性匹配列表template(pattern, flags=0)
编译模板正则,返回一个正则对象
- time模块
datetime.timedelta
求两个datetime对象的差值datetime.strptime
将日期字符串格式化
scrapy 爬虫框架
- 小结
- python 通常以函数为接口,类为处理手段
- re模块有自己的最大缓存,并不能无限抓取
示例
import re
from datetime import datetime, timedelta
from matplotlib import pyplot as plt
from urllib.request import *
def get_html(city, year, month):
url = 'http://lishi.tianqi.com/%s/%s%s.html' % (city, year, month)
# 创建请求
request = Request(url)
request.add_header('User-Agent', 'Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/74.0.3729.108 Safari/537.36')
# 此cookie信息从浏览器中获取
request.add_header('Cookie','BAIDU_SSP_lcr=https://www.baidu.com/link?url=y6zAcbIRa8jW83D6eyOvYFnIVrLKa8lFvwW6UBlMv0TH2nQ4twsjO6Uiig0xRCXiDZcFH1zIsnLyDFuEh5qSYK&wd=&eqid=9260805f00117f98000000035ce2c81a; cityPy=wuhan; cityPy_expire=1558951580; UM_distinctid=16ad4b50e8c102-0aa27a3e148507-3e385d05-100200-16ad4b50e8d14f; CNZZDATA1275796416=1683018428-1558345296-https%253A%252F%252Fwww.cnblogs.com%252F%7C1558361653; Hm_lvt_ab6a683aa97a52202eab5b3a9042a8d2=1558346797,1558346991,1558366253; Hm_lpvt_ab6a683aa97a52202eab5b3a9042a8d2=1558366717')
resp = urlopen(request)
# 获取服务器响应
return resp.read().decode('gbk')
# 数据提取
dates,highs,lows = [],[],[]
city = 'wuhan'
year = '2019'
months = ['01', '02', '03', '04']
prev_day = datetime(2018,12,31)
html = get_html(city,year,'12')
# 循环读取每个月的天气数据
for month in months:
html = get_html(city, year, month)
# 将html响应拼起来
text = "".join(html.split())
# 定义包含天气信息的div的正则表达式
patten = re.compile('<divclass="tqtongji2">(.*?)</div><divstyle="clear:both">')
table = re.findall(patten, text)
patten1 = re.compile('<ul>(.*?)</ul>')
uls = re.findall(patten1, table[0])
for ul in uls:
# 定义解析天气信息的正则表达式
patten2 = re.compile('<li>(.*?)</li>')
lis = re.findall(patten2, ul)
# 解析得到日期数据
d_str = re.findall('>(.*?)</a>', lis[0])[0]
try:
# 将日期字符串格式化为日期
cur_day = datetime.strptime(d_str, '%Y-%m-%d')
# 解析得到最高气温和最低气温
high = int(lis[1])
low = int(lis[2])
except ValueError:
print(cur_day, '数据出现错误')
else:
# 计算前、后两天数据的时间差
diff = cur_day - prev_day
# 如果前、后两天数据的时间差不是相差一天,说明数据有问题
if diff != timedelta(days=1):
print('%s之前少了%d天的数据' % (cur_day, diff.days - 1))
dates.append(cur_day)
highs.append(high)
lows.append(low)
prev_day = cur_day
# 数据可视化
# 配置图形
fig = plt.figure(dpi=128, figsize=(12, 9))
# 绘制最高气温的折线
plt.plot(dates, highs, c='red', label='最高气温',
alpha=0.5, linewidth = 2.0)
# 再绘制一条折线
plt.plot(dates, lows, c='blue', label='最低气温',
alpha=0.5, linewidth = 2.0)
# 为两个数据的绘图区域填充颜色
plt.fill_between(dates, highs, lows, facecolor='blue', alpha=0.1)
# 设置标题
plt.title("广州%s年最高气温和最低气温" % year)
# 为两条坐标轴设置名称
plt.xlabel("日期")
# 该方法绘制斜着的日期标签
fig.autofmt_xdate()
plt.ylabel("气温(℃)")
# 显示图例
plt.legend()
ax = plt.gca()
# 设置右边坐标轴线的颜色(设置为none表示不显示)
ax.spines['right'].set_color('none')
# 设置顶部坐标轴线的颜色(设置为none表示不显示)
ax.spines['top'].set_color('none')
plt.show()