繁体   English   中英

简单移动平均线(SMA)功能

[英]Function for Simple Moving Average (SMA)

我具有以下用于在python中计算SMA的功能:

import numpy as np

def calcSma(data, smaPeriod):
    sma = []
    count = 0
    for i in xrange(data.size):
        if data[i] is None:
            sma.append(None)
        else:
            count += 1
            if count < smaPeriod:
                sma.append(None)
            else:
                sma.append(np.mean(data[i-smaPeriod+1:i+1]))

    return np.array(sma)

该函数有效,但是我发现它很少使用pythonic。 我不喜欢我正在做的索引和计数,也不喜欢我必须追加到列表然后在返回之前将其转换为numpy数组的方式。

我必须处理所有这些None的原因是因为我想返回一个与输入数组大小相同的数组。 这使得以后在一般级别上进行绘制和处理变得更加容易。 我可以轻松地执行以下操作:

sma = calcSma(data=data, smaPeriod=20)
sma2 = calcSma(data=sma, smaPeriod=10)
plt.plot(data)
plt.plot(sma)
plt.plot(sma2)
plt.show()

那么,关于如何更漂亮,更Python化的想法呢?

我希望Pythonic足够

import numpy as np


def calcSma(data, smaPeriod):
    j = next(i for i, x in enumerate(data) if x is not None)
    our_range = range(len(data))[j + smaPeriod - 1:]
    empty_list = [None] * (j + smaPeriod - 1)
    sub_result = [np.mean(data[i - smaPeriod + 1: i + 1]) for i in our_range]

    return np.array(empty_list + sub_result)

这是仅使用标准Python库的移动平均的另一种实现:

from collections import deque
import itertools

def moving_average(iterable, n=3):
    # http://en.wikipedia.org/wiki/Moving_average
    it = iter(iterable) 
    # create an iterable object from input argument
    d = deque(itertools.islice(it, n-1))  
    # create deque object by slicing iterable
    d.appendleft(0)
    s = sum(d)
    for elem in it:
        s += elem - d.popleft()
        d.append(elem)
        yield s / n

# example on how to use it
for i in  moving_average([40, 30, 50, 46, 39, 44]):
    print(i)

# 40.0
# 42.0
# 45.0
# 43.0

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM