Comparé le temps de calcul de la moyenne mobile écrite en Python Donc, j'ai trouvé que la moyenne mobile (LWMA) utilisant l'instruction for est lente et inutilisable, mais certains des indicateurs techniques de MetaTrader ne peuvent pas être écrits sans utiliser l'instruction for, donc je ne peux pas abandonner. Alors j'ai essayé de l'accélérer.
Pour le moment, je savais qu'il y avait Cython pour accélérer, mais c'était que je devais réécrire le code, donc quand j'ai regardé dans d'autres choses, il y avait Numba. Cette fois, c'est un mémo quand j'ai essayé Numba.
import numpy as np
import pandas as pd
dataM1 = pd.read_csv('DAT_ASCII_EURUSD_M1_2015.csv', sep=';',
names=('Time','Open','High','Low','Close', ''),
index_col='Time', parse_dates=True)
def LWMA(s, ma_period):
y = pd.Series(0.0, index=s.index)
for i in range(len(y)):
if i<ma_period-1: y[i] = 'NaN'
else:
y[i] = 0
for j in range(ma_period):
y[i] += s[i-j]*(ma_period-j)
y[i] /= ma_period*(ma_period+1)/2
return y
%timeit MA = LWMA(dataM1['Close'], 10)
1 loop, best of 3: 3min 14s per loop
Comme pour l'article précédent, cela prendra plus de 3 minutes.
Numba semble être dans Anaconda, alors importez et ajoutez simplement @ numba.jit
.
import numba
@numba.jit
def LWMA(s, ma_period):
y = pd.Series(0.0, index=s.index)
for i in range(len(y)):
if i<ma_period-1: y[i] = 'NaN'
else:
y[i] = 0
for j in range(ma_period):
y[i] += s[i-j]*(ma_period-j)
y[i] /= ma_period*(ma_period+1)/2
return y
%timeit MA = LWMA(dataM1['Close'], 10)
1 loop, best of 3: 3min 14s per loop
Oh, le même résultat. Cela n'a aucun effet. Numba est-il dédié à Numpy par son nom?
J'ai changé les données d'entrée du type pandas Series au type de tableau numpy.
@numba.jit
def LWMA(s, ma_period):
y = np.zeros(len(s))
for i in range(len(y)):
if i<ma_period-1: y[i] = 'NaN'
else:
y[i] = 0
for j in range(ma_period):
y[i] += s[i-j]*(ma_period-j)
y[i] /= ma_period*(ma_period+1)/2
return y
%timeit MA = LWMA(dataM1['Close'].values, 10)
1 loop, best of 3: 2.11 s per loop
Cette fois, c'est plus rapide. Environ 90 fois. Cependant, il est encore lent par rapport à quelques millisecondes de scipy.
Même lors de la compilation, il est décidé que le code doit être simple, j'ai donc supprimé l'instruction if. En fait, cette instruction if était un code qui peut être présent ou non.
@numba.jit
def LWMA(s, ma_period):
y = np.zeros(len(s))
for i in range(len(y)):
for j in range(ma_period):
y[i] += s[i-j]*(ma_period-j)
y[i] /= ma_period*(ma_period+1)/2
return y
%timeit MA = LWMA(dataM1['Close'].values, 10)
100 loops, best of 3: 5.73 ms per loop
sortit de! milliseconde. Même s'il y avait une instruction for, elle pourrait être aussi rapide que scipy. Vous pouvez le faire, Python.
Le code qui a été ralenti à l'aide de l'instruction for pourrait être accéléré à l'aide de Numba. Cependant, cela fonctionnait pour numpy et n'avait aucun effet sur les pandas.
Je pensais qu'il était lent d'utiliser l'instruction for dans NumPy, mais ce n'était pas le cas
Recommended Posts