2017-12-22 32 views
4

for this for 루프를 대체하기 위해 list comprehension을 사용하려고합니다. 내 목록 기능은for this loop for list comprehension을 만드는 방법

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 = [3, 4, 6, 3, 8, 4, 7, 8, 12, 14, 1, 6, 7, 3, 7, 8, 3, 3, 7] 

입니다 (test_list, 5) 나는이

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 
시도

[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] 

될 것입니다

그러나 ema_com을 호출하면 결과가 달라집니다. 홍보 (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] 
  1. 이 목록의 이해를 얻을 수 있다면 내가 좋아하는 것입니다.
  2. 작성되지 않은 요소에 액세스하려고하기 때문에 목록 이해 결과가 달라 집니까?
+0

. 나는 x가 "test_list"라고 생각한다. 어때? – skilledDt

+0

그는 그의 질문에서'ema_compr (test_list, 5)'의 결과가 무엇인지 말합니다. – Sebastian

답변

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

을 제공합니다 : x와 N의 값이 무엇인지

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] 
1

난 그냥 팬더의 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() 
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] 
0

목록 작성에서 i를 사용하려고합니다. 배열을 저장하지 않고 ndex emaint[i-1]. 그것은 전체 배열을 반복하면 지능형리스트에 저장됩니다

당신은

for i in range(0,len(x)): 
    if i<=n: 
     emaint[i]=np.average(x[:n]) 
    else: 
     emaint[i]=((x[i] * k) + (emaint[i - 1] * (1 - k))) 

(이 거의 첫 번째 솔루션처럼) 요소를 설정하려면이 같은 루프 쓸 수 있습니다 및 다음 반복에 갈 수

또는 Sebastian에서 제안한대로 팬더를 사용할 수 있습니다.

+0

고맙습니다. 당신은 바로 그 자리에 있고, 나는 if ...를 피하려고 노력하고 있었고 그 대답은 나의 출발점이었습니다. 그래프 속도를 향상 시키려고 할 때 첫 번째 부분을 루프 밖으로 이동시킵니다. 나는 @sebastian 대답을 시도하지만 조금 느립니다. 내 질문에 속도 요소에 대해 언급 해야겠다. –