2

我在列表中有一些事件时间,我想绘制它们的指数加权移动平均值。我可以使用以下代码执行此操作。

import numpy as np
import matplotlib.pyplot as plt

print "Code runnning"
a=0.01
l = [3.0,7.0,10.0,20.0,200.0]
y = np.zeros(1000)
for item in l:
        y[item]=1
s = np.zeros(1000)
x = np.linspace(0,1000,1000)
for i in xrange(1000):
    s[i] = a*y[i-1]+(1-a)*s[i-1]
plt.plot(x, s)
plt.show()

然而,这显然是一种使用 python 的可怕方式。这样做的正确方法是什么?是否可以在不制作所有这些额外的稀疏数组的情况下做到这一点?

输出应如下所示。

在此处输入图像描述

4

3 回答 3

1

为了这项任务,我想到了Pandas :

import pandas as pd

l = [3.0,7.0,10.0,20.0,200.0]
s = pd.Series(np.ones_like(l), index=l)
y = s.reindex(range(1000), fill_value=0)
pd.ewma(y, 199).plot()

期间199与您的参数 alpha 0.01相关n=2/(a+1)。结果: 在此处输入图像描述

于 2013-08-19T18:53:00.523 回答
0

AFAIK 没有一个很好的方法来使用numpyscipy.sparse模块 - 稀疏矩阵scipy.sparse被设计为二维矩阵,并且首先创建一个你基本上需要使用你已经编写的代码您的第一个循环(即,设置稀疏矩阵中的所有非零位置),具有始终必须指定两个索引值的额外复杂性。

好像这还不够糟糕,np.convolve不适用于稀疏数组,所以你仍然需要在第二个循环中写出计算来计算移动平均值。

如果您正在寻找一个花哨的numpy版本,我的建议可能没有太大帮助,那就是依赖 Python 作为通用语言的出色支持:

import matplotlib.pyplot as plt

a=0.01
l = set([3, 7, 10, 20, 200])
s = np.zeros(1000)
for i in xrange(len(s)):
    s[i] = a * int(i-1 in l) + (1-a) * s[i-1]
plt.plot(s)
plt.show()

在这里,我已经将事件索引值存储在 l 中,就像你做的那样,但是我使用 aset来使查找时间 O(1) - 虽然如果len(l)不是很大,你甚至可能会更好地使用一个简单的列表或元组,您需要对其进行测量以确定。然后,您可以避免创建y数组,而只需依靠Iverson 的约定将 Boolean 值x in y转换为int. 您甚至可能不需要显式转换,但我发现显式很有帮助。

于 2013-08-19T18:52:52.957 回答
0

我想你正在寻找这样的东西:

import numpy as np
import matplotlib.pyplot as plt
from scikits.timeseries.lib.moving_funcs import mov_average_expw

l = [ 3.0, 7.0, 10.0, 20.0, 200.0 ]
y = np.zeros(1000)
y[[l]] = 1
emav = mov_average_expw(y, 199)
plt.plot(emav)
plt.show()

这利用了mov_average_expwfrom scikits.timeseries。检查该方法的文档,看看我是如何根据您的代码a变量提出 span 参数的。

于 2013-08-19T19:18:37.710 回答