Python/下载数据


本篇将访问并可视化以两种常见格式存储的数据:CSV和JSON。将使用Python模块csv来处理CSV格式存储的天气数据,找出两个不同地区在一段时间内的最高温度和最低温度。然后,我们将使用matplotlib根据下载的数据创建一个图表,展示两个不同地区的气温变化:阿拉斯加锡特卡和加州死亡谷;将使用模块json来访问以JSON格式存储的交易收盘价数据,并使用Pygal绘制图形以探索价格变化的周期性

处理CSV文件

书籍配套资源下载源代码,获得数据文件sitka_weather_07-2014.csv到project文件夹下

分析CSV头文件

打开srv文件,获取srv首行头文件数据,且对应其其索引打印出来

# highs_lows.py
import csv

from sqlalchemy import column

file_name = 'sitka_weather_07-2014.csv'
with open(file_name) as f:
    reader = csv.reader(f)
    header_row = next(reader)
    # 调用next()一次,因此得到的是文件的第一行数据
    for index, column_header in enumerate(header_row):        
        # 使用enumerate()获得每个元素的索引及其值
        print(index, column_header)

提取并读取数据

获取Max temperature列的数据

# highs_lows.py
 --snip--
 with open(filename) as f:
 	highs=[]
 	--snip--
    for row in reader:
        highs.append(int(row[1]))
        # 从首行文件头可知处于第二列的 Max TemperatureF 及为高温度
    print(highs)

绘制气温图表

将所获取的highs利用matplotlib的pyplot模块,用plot()绘制出折线图

# highs_lows.py
--snip--
fig = plt.figure(dpi=128, figsize=(10, 6))
plt.plot(highs, c='red')

plt.title('Daily high temperatures, July 2014', fontsize=24)
plt.xlabel('Daily', fontsize=16)
plt.ylabel('Temperature (F)', fontsize=16)
plt.tick_params(axis='both', which='major', labelsize=16)

plt.show()

使用datetime模块获取日期

使用datetime模块中的datetime类,调用strptime()方法接收各种实参,并因此决定解读日期

>>>from datetime import datetime
>>>first_data = datetime.strptime('2014-7-1', '%Y-%m-%d')
>>>Xprint(first_date)
2014-07-01 00:00:00

datetime中设置日期和时间格式的实参

# highs_lows.py
import csv
from matplotlib import pyplot as plt
from datetime import datetime

file_name = 'sitka_weather_07-2014.csv'
with open(file_name) as f:
    reader = csv.reader(f)
    header_row = next(reader)
    head_file = {}
    dates, highs = [], []
    # 调用next()一次,因此得到的是文件的第一行数据
    for index, column_header in enumerate(header_row):
        # 使用enumerate()获得每个元素的索引及其值
        head_file[index] = [column_header]
        #print(index, column_header)
    for row in reader:
        # 提取每行数据
        highs.append(int(row[1]))
        # 从首行文件头可知处于第二列的 Max TemperatureF 及为高温度
        current_date = datetime.strptime(row[0], "%Y-%m-%d")
        dates.append(current_date)
        # print(highs)

fig = plt.figure(dpi=128, figsize=(10, 6))
plt.plot(dates, highs, c='red')

plt.title('Daily high temperatures, July 2014', fontsize=24)
plt.xlabel('Daily', fontsize=16)
fig.autofmt_xdate()
# 绘制倾斜的日期
plt.ylabel('Temperature (F)', fontsize=16)
plt.tick_params(axis='both', which='major', labelsize=16)

plt.show()

在这里插入图片描述

添加最低温度折线

新增lows列表变量,记录2014的最低温度值,用于后续plot()方法中绘制出来

# highs_lows.py
import csv
from matplotlib import pyplot as plt
from datetime import datetime

file_name = 'sitka_weather_2014.csv'
with open(file_name) as f:
    reader = csv.reader(f)
    header_row = next(reader)
    head_file = {}
    dates, highs, lows = [], [], []
    # 调用next()一次,因此得到的是文件的第一行数据
    for index, column_header in enumerate(header_row):
        # 使用enumerate()获得每个元素的索引及其值
        head_file[index] = [column_header]
        #print(index, column_header)
    for row in reader:
        # 提取每行数据
        highs.append(int(row[1]))
        lows.append(int(row[3]))
        # 从首行文件头可知处于第二列的 Max TemperatureF 及为高温度
        current_date = datetime.strptime(row[0], "%Y-%m-%d")
        dates.append(current_date)
        # print(highs)

fig = plt.figure(dpi=128, figsize=(10, 6))
plt.plot(dates, highs, c='red')
plt.plot(dates, lows, c='blue')

plt.title('Daily high temperatures, 2014', fontsize=20)
plt.xlabel('Daily', fontsize=16)
fig.autofmt_xdate()
# 绘制倾斜的日期
plt.ylabel('Temperature (F)', fontsize=16)
plt.tick_params(axis='both', which='major', labelsize=10)

plt.show()


给图表区域着色

之前的案例已经显示了最高、低温度的折线,使用fill_between()方法,接收一个x值和两个y值,并填充两个y值系列之间的空间

# highs_lows.py
fig=plt.figure(dpi=128, figsize=(10, 6))
plt.plot(dates, highs, c='red', alpha=0.5)
plt.plot(dates, lows, c='blue', alpha=0.5)
plt.fill_between(dates, highs, lows, facecolor='blue', alpha=0.1)
# alpha参数指定颜色的透明度,0为完全透明,1为完全不透明

处理JSON文件

本节将使用到JSON格式的交易收盘价数据,并使用json模块处理它们,对收盘价数据进行可视化,以探索价格变化的周期性
需下载btc_close_2017.json文件
这个文件里是python列表,每个元素是包含5个键值对的字典dic:日期,月份,周数,周几,收盘价

下载json文件数据

从Github上下载btc_close_2017.json数据

# btc_close_2017.py
from urllib.request import urlopen
import json
json_url = <.json文件url路径> # 'https://raw.githubsercontent.com/muxuezi/btc/master/btc_close_2017.json'
response=urlopen(json_url)
# python向Github服务器发送请求btc_close_2017.json
req=response.read()
# 读取数据
with open(<.json文件物理地址>, 'wb') as f:
	# 将数据写入文件
	f.write(req)

file_urllib=json.loads(req)
# 加载json格式,将文件内容转换成python能处理的格式,与直接下载的文件内容一致
print(file_urllib)

另外可以使用requests模块get()方法获取数据

import requests
json_url = <.json文件url地址>
req=requests.get(json.url)

with open (<.json文件物理地址>, 'w') as f:
	f.write(req.text)
	# req的text属性可直接读取文件数据,返回字符串
file_requests=req.json()
# 将json文件的数据转换成python列表file_requests,与此前file_urllib内容相同

提取相关数据

import json
filename='btc_close_2017.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 = float(btc_dict['close'])
	print(' the date is {}, the month is {}, the week is {}, the weekday is {}, the close price is {} RMB'.format(date, month, week, weekday, close))

即可打印列表中每个字典的键值对

绘制收盘价折线图

本例使用pygal来实现收盘价的折线图

# btc_close_2017.py
import json
import pygal
filename='btc_close_2017.json'
with open(filename) as f:
	btc_data=json.load(f)

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(float(btc_dict['close']))
print(len(dates))
line_chart = pygal.Line(x_label_rotation=20, show_minor_x_labels=False)
# x_laber_rotation=20,令x坐标标签顺时针转20,show_minor_x_laberls=False,令不用显示所有x轴标签
line_chart._title = "close price"
line_chart.x_labels = dates
N = 20
line_chart._x_labels_major = dates[::N]
# 设置_xlabels_major属性,令x轴坐标隔20个显示一次
line_chart.add('close price', close)
line_chart.render_to_file('images/close price picture.svg')

研究时间序列的趋势,周期性,噪声;一般对非线性的趋势消除,进行logtransformation对数变换

import math
-snip-
print(len(dates))
line_chart = pygal.Line(x_label_rotation=20, show_minor_x_labels=False)
# x_laber_rotation=20,令x坐标标签顺时针转20,show_minor_x_laberls=False,令不用显示所有x轴标签
line_chart._title = "close price logtransfomation"
line_chart.x_labels = dates
N = 20
line_chart.x_labels_major = dates[::N]
# 设置_xlabels_major属性,令x轴坐标隔20个显示一次
close_log=[math.log10(n) for n in close]
line_chart.add('close price logtransformation', close_log)
line_chart.render_to_file('images/close price logtransformation picture.svg')

数据统计分析

利用json文件中的数据,绘制日均值,以及每周各天的日均值。可以将之前绘图代码封装成函数draw_line(x_data, y_data, title, y_legend),以便重复调用

封装函数—groupby()

python中的groupby函数主要的作用是进行数据的分组以及分组后的组内运算,for key group in groupby(列表, lambda c: c.function()),实际上挑选规则是通过函数完成的,只要作用于函数的两个元素key相同,就能被分到同一组,返回key对应的每一组group;
y_list = [v for _, v in y]这一行代码还不理解,显然-就是key, [ ]就是一个生成器,用于获取对应key的group中的元素

from itertools import groupby
# groupby函数的主要作用是进行数据分组以及分组后的组内运算
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('images/'+title+'.svg')
    return line_chart

数据筛选

查看月日均值

# btc_close_2017.py
-snip-
idx_month = dates.index('2017-12-01')
# index()方法用于从列表中找出某个值第一个匹配项的索引值
line_chart_month = draw_line(months[:idx_month], close[:idx_month],
                       'close monthly average price', 'monthly average price')
line_chart_month

查看周日均值

# btc_close_2017.py
-snip-
idx_month = dates.index('2017-12-01')
# index()方法用于从列表中找出某个值第一个匹配项的索引值
line_chart_month = draw_line(weeks[1:idx_month], close[1:idx_month],
                       'close weekly average price', 'weekly average price')
line_chart_month
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值