本章节内容节自《python编程从入门到实践》第十六章,我们将从网络上下载数据,并对数据进行可视化。就可以对其进行分析甚至观察其规律和关联。
学习目标
我们将访问并可视化以下两种常见格式存储的数据:
-
CSV
使用 Python 模块 CSV 来处理以 CSV格式存储的天气数据,找出两个不同地区在同一个时间段内的最高气温和最低温度。然后 使用 matplotlib 根据下载的数据创建一个图表,展示两个不同地区的气温变化 -
JSON
使用 Python 模块 json来访问 JSON格式存储的交易收盘价格数据,并使用Pygal 绘制图形以探索价格变化的周期性
以下内容只涵盖 如何下载JSON格式的数据.
CSV 格式请翻阅:
使用python 下载CSV格式数据
前言
上篇文章的学习,不仅了解了使用 python 下载 csv格式的数据,并且还知道了 可以通过matplotlib 将所下载到的数据绘制成图,以便更好的观察数据。
而json格式的数据 python 也提供了相应的处理方式,也就是通过 json模块进行处理。并且可以通过 Pygal 进行可视化。
1. 下载收盘价数据
准备好分享给大家的这个文件:
将这个准备好的文件,放到将要编写的程序文件同级下。
.
.
然后开始正式的学习阶段:
.
.
如果你打开该文件
发现其实其内部就是一个很长的Python列表。其中每个元素都是一个包含五个键的字典。用于统计:日期、月份、周数、周几以及收盘价格信息。
好了好了好了~
开始尝试下载数据:
1.1 使用 urlopen 来下载数据
要使用 rulopen 就需要先进行导入.
from __future__ import (absolute_import,division,print_function,unicode_literals)
try:
from urllib2 import urlopen
except ImportError:
from urllib.request import urlopen
import json
而在导入过程中可能会出现版本的纠纷问题,所以我们这样编码.
其好处在于:
用 try/except 语句实现兼容。ImportError 可作为判断,如果使用 python2相关内容,就执行python2 代码行的导入过程,如果运行 python3 相关代码行,由于没有 urllib2模块,解释器就会出发 ImportError 然后执行 python3 相关代码行。
这里导入的 json 是为了方便后续能够正确加载文件中的数据。
然后,我们继续编码:
from __future__ import (absolute_import,division,print_function,unicode_literals)
try:
from urllib2 import urlopen
except ImportError:
from urllib.request import urlopen
import json
json_url = 'https://raw.githubusercontent.com/muxuezi/btc/master/btc_close_2017.json'
response = urlopen(json_url)
#读取数据
req = response.read()
# 将数据写入文件
with open('btc_close_2017_urllib.json','wb') as f:
f.write(req)
# 加载 json 格式数据
file_urllib = json.loads(req)
print(file_urllib)
程序运行之后,会出现一个 bug,解决这个bug需要自己手动改一下自己电脑的相关设置。
我把更改的链接放在这里了:按照这个步骤设置一下即可解决问题
在运行看一下输出结果:
当然结果并不是最重要的,重要的是搞清楚每句代码的含义和编写整段代码的思路!
思路回溯:
urllib 模块的 urlopen 函数
urlopen函数,可以帮助我们处理文件中的数据。而导入过程中担心其可能会出现版本问题,所以这里加入了异常处理。
如果使用 python2 相关模块,就执行 try 中的代码行。
如果没有找到 python2 相关模块,解释器将会触发 ImportError
json 模块
在接着就是导入 json 模块,以便之后能够正确加载文件中的数据。
btc_close_2017.json 文件存放在 github 网站上。
urlopen(json_url) 将 json_rul 网址传入 urlopen函数。
执行该代码语句,python 就会向 github 服务器发送请求。github的服务器响应请求后把 btc_close_2017.json 文件发送给 python,之后用 response.read() 就可以读取文件数据。这时便可以将文件数据保存到文件夹中。
函数 json.load()
该函数负责将文件内容转换成 python 能够处理的格式,与前面直接下载的文件内容一致。
上述便是用 urlopen函数的读写方式
下面我们在通过 第三方模块 request 封装的方法来下载和读取数据:
1.2 通过 request 下载和读取数据
:
request 是第三方封装的方法,较比于 urlopen 简单一些。
不在需要考虑版本问题,我们直接来看代码:
import request
json_url = 'https://raw.githubusercontent.com/muxuezi/btc/master/btc_close_2017.json'
req = requests.get(json_url)
#将数据写入文件
with open('btc_close_2017_request.json','w') as f:
f.write(req.text)
file_requests = req.json()
代码片段说明:
request 通过get方法向 GitHub 服务器发送请求。服务器接收到请求之后,返回的结果存储到 req变量当中。req.text属性可以直接读取文件数据,返回格式是字符串,可以像之前一样保存为文件 btc_colose_2017_request.json,其内容与btc_close_2017_urllib.json一样。另外 req.json() 就可以将 btc_close_2017.json文件的数据转换为 python 列表file_requests,与之前的file_urllib内容相同。
1.3 提取相关内容
接下来,我们可以编写一个小程序来提取 btc_close_2017.json 文中的相关信息:
btc_close_2017.py:
import json
filename = 'btc_close_2017_request.json'
with open(filename) as f:
btc_date = json.load(f)
for btc_dict in btc_date:
date = btc_dict['date']
month = btc_dict['month']
week = btc_dict['week']
weekday = btc_dict['weekday']
close = btc_dict['close']
print("{} is month {} week {},{}, the close price is {} RMB".format(date,month,week,weekday,close))
这里我们首先导入了 json 模块,然后将数据存储在 btc_data 中。
在通过遍历 btc_data 当中的数据,将其打印出来,需要注意的是 btc_data 当中的每个元素都是一个字典,包含五个键-值对。
看一下输出结果:
虽然我们现在掌握了 json 读取数据的方法。可是还不了解将数据转换为 pygal 能够处理的格式。
我们继续学习:
1.4 将字符串转换为数字值
1.3 demo 中的每个健和值都是字符串,为了能够在后面的内容中对交易数据进行计算,需要先将表示周数和收盘价的字符串转换为数值(通过 int 函数)。
import json
filename = 'btc_close_2017_request.json'
with open(filename) as f:
btc_data = json.load(f)
for btc_dict in btc_date:
date = btc_dict['date']
month = int(btc_dict['month'])
week = int(btc_dict['week'])
weekday = btc_dict['weekday']
close = int(float(btc_dict['close']))
print("{} is month {} week {},{}, the close price is {} RMB".format(date,month,week,weekday,close))
有了处理好的数据,我们可以将这些数据绘制到折线图上
1.5 绘制收盘价折线图
使用 pygal 来实现收盘价的折线图。
在绘制折线图之前,需要获取 x轴 与 y轴数据,所以我们创建几个列表来存储数据。
遍历 btc_data,将转换为适当格式的数据存储到对应的列表中。
#创建五个列表,分别存储日期和收价盘
dates = []
months = []
weeks = []
close = []
# 每一天的信息
for btc_dict in btc_data:
dates.append(btc_dict['date'])
months.append(int(btc_dict['month']))
weeks.append(int(btc_dict['week']))
weeks.append(btc_dict['weekday'])
close.append(int(float(btc_dict['close'])))
由于数据较多,x轴要显示 346个日期,在有限的屏幕上会显得十分拥挤,
我们需要利用 pygal 的配置参数,对图形进行适当的调整。
line_chart = pygal.Line(x_lable_rotation =20, show_minor_x_labels = False)
line_chart.title = '收价盘(¥)'
line_chart.x_labels = dates
N = 20 #x坐标每隔20天显示一次
line_chart.x_labels_major = dates[::N]
line_chart.add('收盘价',close)
line_chart.render_to_file('收盘价折线图(¥).svg')
折线图显示效果: