数据分析JSON板块的基本使用(以分析比特币收盘价为例),附完整的Python代码及json文件详解---数据可视化

一、前提准备

btc_close_2017.json文件下载

链接:点击此处
提取码:zry9

二、将收盘价用可视化图表示出来

上代码

# coding = utf-8

import json
import pygal

# import requests
"""下载收盘数据(注明:这个url有问题,我用多台电脑测试了都是报错的,但是方法是没错的,直接从网上下载了json文件,见btc_close_2017.json)"""
# 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()

"""将数据加载到一个列表当中"""
filename = 'btc_close_2017.json'
with open(filename) as f:
    # 将数据存储在btc_data中
    btc_date = json.load(f)

# 创建5个列表,分别存储日期和收盘价
dates = []
months = []
weeks = []
weekdays = []
close = []
# 打印每一天的信息
for btc_dict in btc_date:
    dates.append(btc_dict['date'])
    months.append(int(btc_dict['month']))
    weeks.append(int(btc_dict['week']))
    weekdays.append(btc_dict['weekday'])
    close.append(int(float(btc_dict['close'])))

"""
有了x轴与y轴的数据,就可以绘制折线图了。由于数据点比较多,x轴要显示346个日期,
在有限的屏幕上会显得十分拥挤。因此我们需要pygal的配置参数,对图形进行适当的调整
"""
# 创建Line实例时,分别设置x_label_rotation、show_minor_x_labels作为初始化参数
# x_label_rotation=20让x轴上的日期标签顺时针旋转20°,show_minor_x_labels=False告诉图形不用显示所有的x轴标签
line_chart = pygal.Line(x_label_rotation=20, show_minor_x_labels=False)
line_chart.title = '收盘价(¥)'
line_chart.x_labels = dates
# x轴坐标每隔20天显示一次
N = 20
line_chart.x_labels_major = dates[::N]
line_chart.add('收盘价', close)
line_chart.render_to_file('收盘价折线图(¥).svg')

运行结果

在这里插入图片描述
注意:上图是以网页的形式表示出来的,在文件目录下面找到他双击
在这里插入图片描述

三、进行时间序列分析

  进行时间序列分析总是期望发现趋势,周期性和噪声,从而能够描述事实,预测未来,做出决策。
由上面的折线图,在每个季度末(3、6、9月)似乎有一些相似的波动。为了验证周期性的假设,我们用python的math模块来解决这个问题,这里用math里面的以10为底的对数函数math.log10计算收盘价,日期仍保持不变,这种方式称作半对数变换。

上代码

# coding = utf-8

import json
import pygal
import math

# import requests
"""下载收盘数据(注明:这个url有问题,我用多台电脑测试了都是报错的,但是方法是没错的,直接从网上下载了json文件,见btc_close_2017.json)"""
# 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()

"""将数据加载到一个列表当中"""
filename = 'btc_close_2017.json'
with open(filename) as f:
    # 将数据存储在btc_data中
    btc_date = json.load(f)

# 创建5个列表,分别存储日期和收盘价
dates = []
months = []
weeks = []
weekdays = []
close = []
# 打印每一天的信息
for btc_dict in btc_date:
    dates.append(btc_dict['date'])
    months.append(int(btc_dict['month']))
    weeks.append(int(btc_dict['week']))
    weekdays.append(btc_dict['weekday'])
    close.append(int(float(btc_dict['close'])))

"""
有了x轴与y轴的数据,就可以绘制折线图了。由于数据点比较多,x轴要显示346个日期,
在有限的屏幕上会显得十分拥挤。因此我们需要pygal的配置参数,对图形进行适当的调整
"""
# 创建Line实例时,分别设置x_label_rotation、show_minor_x_labels作为初始化参数
# x_label_rotation=20让x轴上的日期标签顺时针旋转20°,show_minor_x_labels=False告诉图形不用显示所有的x轴标签
line_chart = pygal.Line(x_label_rotation=20, show_minor_x_labels=False)
line_chart.title = '收盘价对数变换(¥)'
line_chart.x_labels = dates
# x轴坐标每隔20天显示一次
N = 20
line_chart.x_labels_major = dates[::N]
close_log = [math.log10(_) for _ in close]
line_chart.add('log收盘价', close_log)
line_chart.render_to_file('收盘价对数变换折线图(¥).svg')

运行结果

在这里插入图片描述

四、收盘价均值

由于需要将函数按月份,数据,周几分组,再计算每组的均值,因此导入python标准库itertools的函数groupby

月日均值

# coding = utf-8

import json
import pygal
import math
from itertools import groupby

# import requests
"""下载收盘数据(注明:这个url有问题,我用多台电脑测试了都是报错的,但是方法是没错的,直接从网上下载了json文件,见btc_close_2017.json)"""
# 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()

"""将数据加载到一个列表当中"""
filename = 'btc_close_2017.json'
with open(filename) as f:
    # 将数据存储在btc_data中
    btc_date = json.load(f)

# 创建5个列表,分别存储日期和收盘价
dates = []
months = []
weeks = []
weekdays = []
close = []
# 打印每一天的信息
for btc_dict in btc_date:
    dates.append(btc_dict['date'])
    months.append(int(btc_dict['month']))
    weeks.append(int(btc_dict['week']))
    weekdays.append(btc_dict['weekday'])
    close.append(int(float(btc_dict['close'])))

def draw_line(x_data, y_data, title, y_legend):
    xy_map = []
    #将x、y轴的数据进行合并排序再进行分组
    for x, y in groupby(sorted(zip(x_data, y_data)), key=lambda _: _[0]):
        y_list = [v for _, v in y]
        #求出每组的均值,存储到xy_map变量中
        xy_map.append([x, sum(y_list) / len(y_list)])
    #将xy_map中存储的x轴y轴的数据分离
    x_unique, y_mean = [*zip(*xy_map)]
    line_chart = pygal.Line()
    line_chart.title = title
    line_chart.x_labels = x_unique
    line_chart.add(y_legend, y_mean)
    line_chart.render_to_file(title + '.svg')
    return line_chart

idx_month = dates.index('2017-12-01')
line_chart_month = draw_line(months[:idx_month], close[:idx_month], '收盘价月日均值(¥)', '月日均值')
line_chart_month

运行结果
在这里插入图片描述

周日均值

# coding = utf-8

import json
import pygal
import math
from itertools import groupby

# import requests
"""下载收盘数据(注明:这个url有问题,我用多台电脑测试了都是报错的,但是方法是没错的,直接从网上下载了json文件,见btc_close_2017.json)"""
# 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()

"""将数据加载到一个列表当中"""
filename = 'btc_close_2017.json'
with open(filename) as f:
    # 将数据存储在btc_data中
    btc_date = json.load(f)

# 创建5个列表,分别存储日期和收盘价
dates = []
months = []
weeks = []
weekdays = []
close = []
# 打印每一天的信息
for btc_dict in btc_date:
    dates.append(btc_dict['date'])
    months.append(int(btc_dict['month']))
    weeks.append(int(btc_dict['week']))
    weekdays.append(btc_dict['weekday'])
    close.append(int(float(btc_dict['close'])))


def draw_line(x_data, y_data, title, y_legend):
    xy_map = []
    # 将x、y轴的数据进行合并排序再进行分组
    for x, y in groupby(sorted(zip(x_data, y_data)), key=lambda _: _[0]):
        y_list = [v for _, v in y]
        # 求出每组的均值,存储到xy_map变量中
        xy_map.append([x, sum(y_list) / len(y_list)])
    # 将xy_map中存储的x轴y轴的数据分离
    x_unique, y_mean = [*zip(*xy_map)]
    line_chart = pygal.Line()
    line_chart.title = title
    line_chart.x_labels = x_unique
    line_chart.add(y_legend, y_mean)
    line_chart.render_to_file(title + '.svg')
    return line_chart


"""
2017-1-02  ---   2017-12-10 (前49周)的日均值
2017年1月1日是周日,归属为2016年52周,因此2017年的第一周从2017年1月2日开始,取数时需要将第一天去掉
另外,2017年第49周周日是2017年12月10日,因此我们通过dates查找2017-12-11的索引位置,确定周数和收盘价的取值范围
"""
idx_weeks = dates.index('2017-12-11')
line_chart_weeks = draw_line(weeks[1:idx_weeks], close[1:idx_weeks], '收盘价周日均值(¥)', '周日均值')
line_chart_weeks

运行结果
在这里插入图片描述

星期均值

# coding = utf-8

import json
import pygal
import math
from itertools import groupby

# import requests
"""下载收盘数据(注明:这个url有问题,我用多台电脑测试了都是报错的,但是方法是没错的,直接从网上下载了json文件,见btc_close_2017.json)"""
# 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()

"""将数据加载到一个列表当中"""
filename = 'btc_close_2017.json'
with open(filename) as f:
    # 将数据存储在btc_data中
    btc_date = json.load(f)

# 创建5个列表,分别存储日期和收盘价
dates = []
months = []
weeks = []
weekdays = []
close = []
# 打印每一天的信息
for btc_dict in btc_date:
    dates.append(btc_dict['date'])
    months.append(int(btc_dict['month']))
    weeks.append(int(btc_dict['week']))
    weekdays.append(btc_dict['weekday'])
    close.append(int(float(btc_dict['close'])))


def draw_line(x_data, y_data, title, y_legend):
    xy_map = []
    # 将x、y轴的数据进行合并排序再进行分组
    for x, y in groupby(sorted(zip(x_data, y_data)), key=lambda _: _[0]):
        y_list = [v for _, v in y]
        # 求出每组的均值,存储到xy_map变量中
        xy_map.append([x, sum(y_list) / len(y_list)])
    # 将xy_map中存储的x轴y轴的数据分离
    x_unique, y_mean = [*zip(*xy_map)]
    line_chart = pygal.Line()
    line_chart.title = title
    line_chart.x_labels = x_unique
    line_chart.add(y_legend, y_mean)
    line_chart.render_to_file(title + '.svg')
    return line_chart


"""
绘制每周中各天的均值
为了使用完整的时间段,还像前面那样取2017-01-02----2017-12-10的数据,同样通过dates来查找2017-12-11的索引位置,确定周数和收盘价的取数范围
但是,由于这里的周几是字符串,按周一到周日的顺序排列,而不是单词首字母的顺序,绘图x轴标签的顺序会有问题。
原来的周几都是英文单词,还可以将其调整为中文
"""
idx_weeks = dates.index('2017-12-11')
# 列出一周7天的英语单词,将weekdays的内容转换为1-7的整数
wd = ['Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday', 'Sunday']
weekdays_int = [wd.index(w) + 1 for w in weekdays[1:idx_weeks]]

line_chart_weekday = draw_line(weekdays_int, close[1:idx_weeks], '收盘价星期均值(¥)', '星期均值')
line_chart_weekday.x_labels = ['周一', '周二', '周三', '周四', '周五', '周六', '周天']
line_chart_weekday.render_to_file('收盘价星期均值(¥).svg')

运行结果
在这里插入图片描述

五、数据仪盘表

前面已经绘制了五幅图,分别是收盘价折线图,收盘价对数变换折线图,收盘价月均值,收盘价周均值,收盘价星期均值,每个svg文件打开都是独立的页面,如果我们能够将他们整合在一起,就可以很方便进行长期管理、检测和分析。另外,新的图表也可以十分方便地加入进来,这样就形成了一个数据仪表盘

# coding = utf-8

import json
import pygal
import math
from itertools import groupby

# import requests
"""下载收盘数据(注明:这个url有问题,我用多台电脑测试了都是报错的,但是方法是没错的,直接从网上下载了json文件,见btc_close_2017.json)"""
# 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()

"""将数据加载到一个列表当中"""
filename = 'btc_close_2017.json'
with open(filename) as f:
    # 将数据存储在btc_data中
    btc_date = json.load(f)

# 创建5个列表,分别存储日期和收盘价
dates = []
months = []
weeks = []
weekdays = []
close = []
# 打印每一天的信息
for btc_dict in btc_date:
    dates.append(btc_dict['date'])
    months.append(int(btc_dict['month']))
    weeks.append(int(btc_dict['week']))
    weekdays.append(btc_dict['weekday'])
    close.append(int(float(btc_dict['close'])))




# 创建Line实例时,分别设置x_label_rotation、show_minor_x_labels作为初始化参数
# x_label_rotation=20让x轴上的日期标签顺时针旋转20°,show_minor_x_labels=False告诉图形不用显示所有的x轴标签
line_chart = pygal.Line(x_label_rotation=20, show_minor_x_labels=False)
line_chart.title = '收盘价(¥)'
line_chart.x_labels = dates
# x轴坐标每隔20天显示一次
N = 20
line_chart.x_labels_major = dates[::N]
line_chart.add('收盘价', close)
line_chart.render_to_file('收盘价折线图(¥).svg')

# 创建Line实例时,分别设置x_label_rotation、show_minor_x_labels作为初始化参数
# x_label_rotation=20让x轴上的日期标签顺时针旋转20°,show_minor_x_labels=False告诉图形不用显示所有的x轴标签
line_chart = pygal.Line(x_label_rotation=20, show_minor_x_labels=False)
line_chart.title = '收盘价对数变换(¥)'
line_chart.x_labels = dates
# x轴坐标每隔20天显示一次
N = 20
line_chart.x_labels_major = dates[::N]
close_log = [math.log10(_) for _ in close]
line_chart.add('log收盘价', close_log)
line_chart.render_to_file('收盘价对数变换折线图(¥).svg')
line_chart

def draw_line(x_data, y_data, title, y_legend):
    xy_map = []
    for x, y in groupby(sorted(zip(x_data, y_data)), key=lambda _: _[0]):
        y_list = [v for _, v in y]
        xy_map.append([x, sum(y_list) / len(y_list)])
    x_unique, y_mean = [*zip(*xy_map)]
    line_chart = pygal.Line()
    line_chart.title = title
    line_chart.x_labels = x_unique
    line_chart.add(y_legend, y_mean)
    line_chart.render_to_file(title + '.svg')
    return line_chart


idx_month = dates.index('2017-12-01')
line_chart_month = draw_line(
    months[:idx_month], close[:idx_month], '收盘价月日均值(¥)', '月日均值')
line_chart_month

idx_week = dates.index('2017-12-11')
line_chart_week = draw_line(
    weeks[1:idx_week], close[1:idx_week], '收盘价周日均值(¥)', '周日均值')
line_chart_week

idx_week = dates.index('2017-12-11')
wd = ['Monday', 'Tuesday', 'Wednesday',
      'Thursday', 'Friday', 'Saturday', 'Sunday']
weekdays_int = [wd.index(w) + 1 for w in weekdays[1:idx_week]]
line_chart_weekday = draw_line(
    weekdays_int, close[1:idx_week], '收盘价星期均值(¥)', '星期均值')
line_chart_weekday.x_labels = ['周一', '周二', '周三', '周四', '周五', '周六', '周日']
line_chart_weekday.render_to_file('收盘价星期均值(¥).svg')
line_chart_weekday

with open('收盘价Dashboard.html', 'w', encoding='utf8') as html_file:
    html_file.write(
        '<html><head><title>收盘价Dashboard</title><meta charset="utf-8"></head><body>\n')
    for svg in [
        '收盘价折线图(¥).svg', '收盘价对数变换折线图(¥).svg', '收盘价月日均值(¥).svg',
        '收盘价周日均值(¥).svg', '收盘价星期均值(¥).svg'
    ]:
        html_file.write(
            '    <object type="image/svg+xml" data="{0}" height=500></object>\n'.format(svg))
    html_file.write('</body></html>')

运行结果
在这里插入图片描述
注意,可放大!
学习《python编程从入门到实战》16章第二节。
以上就是全部内容啦,如果有不懂的小伙伴欢迎提出来傲!

猜你喜欢

转载自blog.csdn.net/hanhanwanghaha/article/details/108167182
今日推荐