3

我需要帮助在我已经能够绘制的数据之上绘制移动平均线(见下文)

我试图使 m(我的移动平均线)等于 y(我的数据)的长度,然后在我的“for”循环中,我似乎对我的移动平均线有正确的数学。

什么有效:绘制 x 和 y

什么不起作用:在 x 和 y 上绘制 m 并给我这个错误

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 ()
4

3 回答 3

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

第二个问题是,为了绘制两组数据,数据点的总数需要相同。您的函数返回一组小于原始数据集的新数据。(您可能没有注意到,因为您预先分配了一个大小相同的 zeros 数组。您的 for 循环将始终生成一个末尾有一堆零的数组。)

卷积函数为您提供正确的数据,但由于参数的原因,它有两个额外的值(每端都有一些)same,这确保新数据数组与原始数据数组具有相同的大小。

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 函数对代码进行矢量化。

In [7]: (cs[3-1:] - np.append(0,cs[:-3]))/3.
Out[7]: array([ 1.,  2.,  3.,  4.,  5.,  6.,  7.,  8.])

(最后一个是对上一篇文章中答案的修改

诀窍可能是您应该删除date数组的第一个值。例如,使用以下绘图调用,n平均点数在哪里:

plt.plot_date(x=date[n-1:], y=m, fmt = '-', color='b')
于 2013-08-19T02:53:00.487 回答
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,这将导致空列表!要修复它,只需替换1i.

此外,您的范围需要在最后扩大一倍。替换y.shape[0]y.shape[0]+1

选择

我只是想我会提到您可以通过使用np.convolve文档)更自动地计算移动平均值:

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)更短,您可以通过删除日期数组的第一个或最后一个元素来解决这个问题。

于 2013-08-17T20:58:54.240 回答
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')
于 2013-08-20T02:05:05.957 回答