本篇依然是数据分析里数据可视化方面的内容,主要内容有一维卷积、完全卷积、有效卷积、移动均线的绘制、布林带的绘制。
一、卷积运算
1、关于卷积
这里说到的卷积计算,是指我们对图像进行某种滤波处理或者是边缘检测、锐化等应用要用到的运算。通常,要进行卷积的话就必须要有一个模板(掩模),这些模板的实际就是在卷积计算是所用到的点乘系数。
2、卷积的运算
a = [1 2 3 4 5] # 被卷积数组
b = [6 7 8] # 卷积核数组
卷积运算:c = a (x) b
得到的卷积
完全卷积(full):[6 19 40 61 82 67 40]
同尾卷积(same):[19 40 61 82 67]
有效卷积(valid):[40 61 82]
3、在numpy中求卷积
- numpy.convolve(a, b, ‘full’/‘same’/‘valid’)
4、练习代码
import numpy as np
a = np.arange(1, 6)
b = np.arange(6, 9)
print('a:', a)
print('b:', b)
# 计算a与b的全full卷积
c_full = np.convolve(a, b, 'full')
print('c_full:', c_full)
# 计算a与b的同尾卷积
c_same = np.convolve(a, b, 'same')
print('c_same:', c_same)
# 计算a与b的有效卷积
c_valid = np.convolve(a, b, 'valid')
print('c_valid:', c_valid)
二、移动均线的绘制
1、何为移动均线
数据数组:[a b c d e]
权重数组:[A B C D E]
- 加权平均值:(aA+bB+cC+dD+eE)/(A+B+C+D+E)
记:S=(A+B+C+D+E) - 移动均线:[A/S B/S C/S D/S E/S]
2、绘制移动均线的步骤
1、获取数据并转换数据类型
2、设置窗口期
3、计算均线各点数据组成的数组
4、图像的基本设置
5、绘制移动均线
3、移动均线案例
import datetime as dt
import numpy as np
import matplotlib.pylab as mp
import matplotlib.dates as md
'''
1、获取数据并转换数据类型
'''
def dmy2ymd(dmy):
dmy = str(dmy, encoding='utf-8') # 转码dmy日期
date = dt.datetime.strptime(dmy, '%d-%m-%Y').date() # 获取时间对象
ymd = date.strftime('%Y-%m-%d')
return ymd
dates, closing_prices = np.loadtxt(
'0=数据源/beer_price.csv', delimiter=',',
usecols=(0, 4), unpack=True,
dtype=np.dtype('M8[D], f8'),
converters={0: dmy2ymd}
)
'''
2、设置窗口期
'''
# 均线数据,5个窗口期
ma5_1 = np.zeros(closing_prices.size - 4)
for i in range(ma5_1.size):
# ma5_1[0] = closing_prices[0:5].mean() # 前五天的平均值
ma5_1[i] = closing_prices[i:i+5].mean()
'''
3、计算均线个点数据组成的数组
'''
# 用卷积的方法做均线
ma5_2 = np.convolve(closing_prices, np.ones(5) / 5, 'valid')
# 时间窗口为10的均线
ma10 = np.convolve(closing_prices, np.ones(10) / 10, 'valid')
# 加上权重的卷积移动均线(加权平均值):
weight = np.exp(np.linspace(-1, 0, 5)) # -1到0分成5份作为指数
weight /= weight.sum() # 除以权重,就加权平均值
ma5_3 = np.convolve(closing_prices, weight[::-1], 'valid')
# weight[::-1]表示取weight的逆序,因为计算卷积时b数组应该是逆序的
# 而对于之前的np.ones(5) / 5 和 np.ones(10) / 10表示的是等权重的,因此逆序与否都是相同的,就不需要逆序了
'''
4、图像的基本设置
'''
# 曲线图基础设置
mp.figure('Moving Average', facecolor='lightgray')
mp.title('Moving Average', fontsize=20)
mp.xlabel('Date', fontsize=14)
mp.ylabel('Price', fontsize=14)
# 主刻度设置为以周一为起始的星期格式
ax = mp.gca() # 获取刻度线(坐标轴)
ax.xaxis.set_major_locator(
md.WeekdayLocator(byweekday=md.MO)
)
# 次刻度设置为以天为单位
ax.xaxis.set_minor_locator(
md.DayLocator()
)
# 主刻度的格式化
ax.xaxis.set_major_formatter(
md.DateFormatter('%d %b %Y')
)
mp.tick_params(labelsize=10) # 字体
mp.grid(linestyle=':') # 网格线
# 绘制曲线
dates = dates.astype(md.datetime.datetime) # 将日期标准化成numpy的日期
mp.plot(dates, closing_prices, c='lightgray', label="Closing Price") # 绘制曲线
'''
5、绘制移动均线
'''
# 绘制移动均线:前5个日期是窗口期,不需要计入均线的点
mp.plot(dates[4:], ma5_1, c='orangered', linewidth=1, label="MA-5-1")
# 绘制移动均线:卷积方法,线更粗,透明度更低
mp.plot(dates[4:], ma5_2, c='orangered', alpha=0.25, linewidth=5, label='MA-5-2')
# 最终结果的两根移动均线完全重合
# 时间窗口为10的移动均线
mp.plot(dates[9:], ma10, c='dodgerblue', linewidth=3, label='MA-10')
# 加权平均值移动均线
mp.plot(dates[4:], ma5_3, c='green', linewidth=3, label='MA-5-3')
mp.legend() # 显示图例
mp.gcf().autofmt_xdate() # 设置格式展示的自动化调整
mp.show() # 显示图像
4、测试效果
三、布林带绘制
1、何为布林带
简单来说就是,可以同时显示价格变化的范围(波动范围)和走势的区域,和移动均线有些类似,具体如下…
2、布林带
- 中轨:移动均线,用来判断趋势
- 上轨:中轨 + 2*标准差,判断上升的最大幅度
- 下轨:中轨 - 2*标准差,判断下降的最大幅度
所谓中轨是就是上文的移动均线,因此这里的布林带只需要多做一步运算就能够求出来各点了,然后就如法炮制,用会绘制移动均线的方法绘制布上轨和下轨,就完成布林带的绘制了。
3、布林带案例
import datetime as dt
import numpy as np
import matplotlib.pylab as mp
import matplotlib.dates as md
def dmy2ymd(dmy):
dmy = str(dmy, encoding='utf-8') # 转码dmy日期
date = dt.datetime.strptime(dmy, '%d-%m-%Y').date() # 获取时间对象
ymd = date.strftime('%Y-%m-%d')
return ymd
dates, closing_prices = np.loadtxt(
'0=数据源/beer_price.csv', delimiter=',',
usecols=(0, 4), unpack=True,
dtype=np.dtype('M8[D], f8'),
converters={0: dmy2ymd}
)
# 中轨:用卷积的方法做均线
N = 5 # 窗口数
medios = np.convolve(closing_prices, np.ones(N) / N, 'valid') # 均线
# 标准差
stds = np.zeros(medios.size)
for i in range(stds.size):
stds[i] = np.std(closing_prices[i:i+N])
# 上轨
uppers = medios + 2*stds
# 下轨
lowers = medios - 2*stds
# 曲线图基础设置
mp.figure('Bollinger Bands', facecolor='lightgray')
mp.title('Bollinger Bands', fontsize=20)
mp.xlabel('Date', fontsize=14)
mp.ylabel('Price', fontsize=14)
# 主刻度设置为以周一为起始的星期格式
ax = mp.gca() # 获取刻度线(坐标轴)
ax.xaxis.set_major_locator(
md.WeekdayLocator(byweekday=md.MO)
)
# 次刻度设置为以天为单位
ax.xaxis.set_minor_locator(
md.DayLocator()
)
# 主刻度的格式化
ax.xaxis.set_major_formatter(
md.DateFormatter('%d %b %Y')
)
mp.tick_params(labelsize=10) # 字体
mp.grid(linestyle=':') # 网格线
# 绘制曲线
dates = dates.astype(md.datetime.datetime) # 将日期标准化成numpy的日期
mp.plot(dates, closing_prices, c='lightgray', label="Closing Price") # 绘制曲线
# 绘制中轨线
mp.plot(dates[N-1:], medios, c='dodgerblue', linewidth=3, label='Medios')
# 最终结果的两根移动均线完全重合
# 绘制上轨线
mp.plot(dates[N-1:], uppers, c='green', linewidth=1, label='Upper')
# 绘制下轨线
mp.plot(dates[N-1:], lowers, c='darkred', linewidth=1, label='Lower')
mp.legend() # 显示图例
mp.gcf().autofmt_xdate() # 设置格式展示的自动化调整
mp.show() # 显示图像
4、测试效果