我需要帮助在我已经能够绘制的数据之上绘制移动平均线(见下文)
我试图让m(我的移动平均线)等于y(我的数据)的长度,然后在我的'for'循环中,我似乎对我的移动平均线有正确的数学。
什么有效:绘制x和y
什么行不通:在x和x之上绘制m? y并给我这个错误
RuntimeWarning:double_scalars中遇到无效值
我的理论:我将m设置为np.arrays = y.shape,然后创建for循环使m等于循环内的数学集,从而将所有0替换为移动平均值
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.dates as mdates
import csv
import math
def graph():
date, value = np.loadtxt("CL1.csv", delimiter=',', unpack=True,
converters = {0: mdates.strpdate2num('%d/%m/%Y')})
fig = plt.figure()
ax1 = fig.add_subplot(1,1,1, axisbg = 'white')
plt.plot_date(x=date, y=value, fmt = '-')
y = value
m = np.zeros(y.shape)
for i in range(10, y.shape[0]):
m[i-10] = y[i-10:1].mean()
plt.plot_date(x=date, y=value, fmt = '-', color='g')
plt.plot_date(x=date, y=m, fmt = '-', color='b')
plt.title('NG1 Chart')
plt.xlabel('Date')
plt.ylabel('Price')
plt.show()
graph ()
答案 0 :(得分:1)
这里的问题存在于你对移动平均线的计算中 - 你只是在索引中遇到了几个一对一的问题!
y = value
m = np.zeros(y.shape)
for i in range(10, y.shape[0]):
m[i-10] = y[i-10:1].mean()
除了:1]
之外,你已经掌握了一切。这告诉解释器从i-10
恰好是什么开始,并在1
之前结束。但如果i-10
大于1
,则会产生空列表!要解决此问题,只需将1
替换为i
。
此外,您的范围最后需要延长一个。将y.shape[0]
替换为y.shape[0]+1
。
我只是想提一下,您可以使用np.convolve
(docs)更自动地计算移动平均线:
m = np.convolve(y, [1. / 10] * 10, 'same')
在这种情况下,m
的长度与y
相同,但移动平均值在开头和结尾可能看起来很奇怪。这是因为'same'
有效地导致y
在两端用零填充,以便在计算卷积时有足够的y
值。
如果您只想获得使用y
(而不是其他零填充)的值计算的移动平均值,则可以将'same'
替换为'valid'
。在这种情况下,正如Ryan指出的那样,m
将比y
(更确切地说,len(m) == len(y) - len(filter) + 1
)更短,您可以通过删除您的第一个或最后一个元素来解决这个问题。日期数组。
答案 1 :(得分:1)
我认为lmjohns3的答案是正确的,但你的移动平均功能有几个问题。首先,lmjohns3指出了索引问题。以下列数据为例:
In [1]: import numpy as np
In [2]: a = np.arange(10)
In [3]: a
Out[3]: array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
您的函数提供以下移动平均值:
In [4]: for i in range(3, a.shape[0]):
...: print a[i-3:i].mean(),
1.0 2.0 3.0 4.0 5.0 6.0 7.0
此数组(7)的大小太小了一个数字。移动平均线的最后一个值应为(7 + 8 + 9)/ 3 = 8。要解决此问题,您可以按如下方式更改功能:
In [5]: for i in range(3, a.shape[0] + 1):
...: print a[i-3:i].sum()/3,
1 2 3 4 5 6 7 8
第二个问题是,为了绘制两组数据,数据点的总数需要相同。您的函数返回一组小于原始数据集的新数据。 (您可能没有注意到,因为您预先分配了一个相同大小的零数组。您的for循环将始终生成一个末尾带有一堆零的数组。)
卷积函数为您提供了正确的数据,但由于same
参数,它有两个额外的值(每端有一些),这可以确保新数据数组与原始数据大小相同。 / p>
In [6]: np.convolve(a, [1./3]*3, 'same')
Out[6]:
array([ 0.33333333, 1. , 2. , 3. , 4. ,
5. , 6. , 7. , 8. , 5.66666667])
作为替代方法,您可以使用Numpy的cumsum function对代码进行矢量化。
In [7]: (cs[3-1:] - np.append(0,cs[:-3]))/3.
Out[7]: array([ 1., 2., 3., 4., 5., 6., 7., 8.])
(最后一个是对previous post中答案的修改。)
诀窍可能是您应该删除date
数组的第一个值。例如,使用以下绘图调用,其中n
是平均值中的点数:
plt.plot_date(x=date[n-1:], y=m, fmt = '-', color='b')
答案 2 :(得分:0)
好吧,无论是我疯了还是实际工作 - 我将我的图表与另一张图表进行了对比,它似乎有效。
这有意义吗?
m = np.zeros(y.shape)
for i in range(10, y.shape[0]):
m[i-10] = y[i-10:i].mean()
plt.plot_date(x=date, y=m, fmt = '-', color='r')