我正在尝试使用list comprehension来替换这个for循环。我的清单是
test_list = [3, 4, 6, 3, 8, 4, 7, 8, 12, 14, 1, 6, 7, 3, 7, 8, 3, 3, 7]
功能是
import numpy as np
def ema(x, n):
x = np.array(x)
emaint = np.zeros(len(x))
k = 2 / float(n + 1)
emaint[0:n] = np.average(x[:n])
for i in range(n, len(x)):
emaint[i] = (x[i] * k) + (emaint[i - 1] * (1 - k))
return emaint
如果我调用ema(test_list,5)的结果将是
[4.8 4.8 4.8 4.8 4.8 4.53333333 5.35555556 6.23703704 8.15802469 10.10534979 7.0702332 6.7134888 6.80899253 5.53932835 6.0262189 6.68414594 5.45609729 4.63739819 5.42493213]
我试过这个
import numpy as np
def ema_compr(x, n):
x = np.array(x)
emaint = np.zeros(len(x))
k = 2 / float(n + 1)
emaint[0:n] = np.average(x[:n])
emaint[n:] = [(x[i] * k) + (emaint[i - 1] * (1 - k)) for i in range(n, len(x))]
return emaint
但是如果我调用ema_compr(test_list,5),结果会有所不同:
[4.8 4.8 4.8 4.8 4.8 4.53333333 2.33333333 2.66666667 4. 4.66666667 0.33333333 2. 2.33333333 1. 2.33333333 2.66666667 1. 1. 2.33333333]
答案 0 :(得分:1)
我建议您只使用Pandas中的ewma
功能:
import pandas as pd
def ema(x, n):
pd_x = pd.Series(x)
pd_x[:n] = pd_x[:n].mean()
return pd.ewma(pd_x, span=n, adjust=False).as_matrix()
答案 1 :(得分:1)
因为你的循环需要保持运行状态,所以尽管存在hacks,但它无法干净地转换为列表理解。
所以,如果你想要"类似"列表理解我推荐下一个最好的东西:累加器。
from itertools import accumulate
def ema(x, n):
xx = n*[sum(x[:n])/n] + x[n:]
p, q = 2 / (n+1), (n-1) / (n+1)
return list(accumulate(xx, lambda a, b: q*a + p*b))
给出:
ema(test_list, 5)
# [4.8, 4.8, 4.8, 4.8, 4.8, 4.533333333333333, 5.355555555555555, 6.2370370370370365, 8.158024691358024, 10.105349794238682, 7.070233196159121, 6.713488797439414, 6.808992531626275, 5.539328354417517, 6.026218902945011, 6.684145935296673, 5.456097290197782, 4.637398193465188, 5.424932128976792]
答案 2 :(得分:0)
在这里,您需要在那里指定索引:
import numpy as np
test_list = [3, 4, 6, 3, 8, 4, 7, 8, 12, 14, 1, 6, 7, 3, 7, 8, 3, 3, 7]
def ema(x, n):
x = np.array(x)
emaint = np.zeros(len(x))
k = 2 / float(n + 1)
emaint[0:n] = np.average(x[:n])
for i in range(n, len(x)):
[emaint.__setitem__(i, ((x[i] * k) + (emaint[i - 1] * (1 - k)))) for i in range(n, len(x))]
return emaint
print(ema(test_list, 5))
输出:
[ 4.8 4.8 4.8 4.8 4.8 4.53333333
5.35555556 6.23703704 8.15802469 10.10534979 7.0702332
6.7134888 6.80899253 5.53932835 6.0262189 6.68414594
5.45609729 4.63739819 5.42493213]
答案 3 :(得分:0)
在列表推导中,您尝试使用索引URLClassPath
而不保存数组。在列表理解中,一旦遍历整个数组
您可以像这样编写循环来设置元素并可以进行下一次迭代(这几乎就像您的第一个解决方案)
emaint[i-1]
或者根据Sebastian的建议,您可以使用Pandas