MyTT icon indicating copy to clipboard operation
MyTT copied to clipboard

cci 计算很慢,有办法提高效率吗?谢谢

Open shenmufeng opened this issue 3 years ago • 2 comments

如题

shenmufeng avatar May 03 '22 10:05 shenmufeng

能优化AVEDEV就能提高效率

def AVEDEV(S, N):         #平均绝对偏差  (序列与其平均值的绝对差的平均值)   
    return pd.Series(S).rolling(N).apply(lambda x: (np.abs(x - x.mean())).mean()).values 

mpquant avatar May 04 '22 02:05 mpquant

import numpy as np
import numba


def rolling_window(a, window):
    shape = a.shape[:-1] + (a.shape[-1] - window + 1, window)
    strides = a.strides + (a.strides[-1],)
    return np.lib.stride_tricks.as_strided(a, shape=shape, strides=strides)
                                           

def AVEDEV2(arr, N):
    res = np.empty(len(arr))
    res[: N-1] = np.nan
    tmp = rolling_window(arr, N)
    
    # for i, arr in enumerate(tmp):
    #     res[N+i-1] = np.mean(np.abs(arr - np.mean(arr)))
        
    return _avedev(tmp, res, N)

@numba.jit
def _avedev(rolling_arr, res, N):
    i = 0
    for arr in rolling_arr:
        res[N+i-1] = np.mean(np.abs(arr - np.mean(arr)))
        i += 1
    return res

Test

arr = np.random.randn(10000)

In [63]: %timeit AVEDEV2(arr, 20) # My version
Out [63]: 1.06 ms ± 1.1 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)

In [64]: %timeit AVEDEV(arr, 20) # original version
Out [64]: 2.29 s ± 12.2 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)

jxxplzwakeup avatar Jun 12 '22 16:06 jxxplzwakeup