À propos du code Python pour une moyenne mobile simple en supposant l'utilisation de Numba

Les moyennes mobiles les plus élémentaires des indicateurs techniques, dont la moyenne mobile simple (SMA) n'est qu'une moyenne, mais elle est utilisée pour calculer de nombreux indicateurs techniques autres que la SMA. En effet, sur la trentaine d'indicateurs techniques affichés sur GitHub, 40% utilisent SMA.

Cette fois, j'aimerais me spécialiser dans ce SMA et comparer du code Python.

Préparation

Depuis que nous avons mis à jour l'ensemble des packages Python, les versions de Python et les packages utilisés sont les suivants.

Tout d'abord Random walk in Python Faites une promenade aléatoire de 100 000 échantillons en vous référant à. Ce seront les données d'entrée pour SMA.

import numpy as np
import pandas as pd
from numba import jit

dn = np.random.randint(2, size=100000)*2-1
gwalk = np.cumprod(np.exp(dn*0.01))*100

Mise en œuvre des pandas par roulement et moyen

L'implémentation la plus simple de SMA est avec les pandas. Il peut être facilement écrit en utilisant les méthodes de série Rolling and Mean.

def SMA1(x, period):
    return pd.Series(x).rolling(period).mean()

Comme spécification courante, entrez la série chronologique d'entrée et la période SMA dans l'argument. Puisque les comparaisons seront faites en fonction de la différence de période, mesurez à période = 20 200.

%timeit y1_20 = SMA1(gwalk, 20)
%timeit y1_200 = SMA1(gwalk, 200)
100 loops, best of 3: 6.02 ms per loop
100 loops, best of 3: 6.01 ms per loop

Dans le cas des pandas, il semble n'y avoir aucune différence de vitesse d'exécution selon la période.

Implémentation de scipy par lfilter

Comparé le temps de calcul de la moyenne mobile écrite en Python Implémentons-le en utilisant la fonction de filtre de scipy lfilter, en référence à.

from scipy.signal import lfilter
def SMA2(x, period):
    return lfilter(np.ones(period), 1, x)/period

Mesurons le temps d'exécution de la même manière.

%timeit y2_20 = SMA2(gwalk, 20)
%timeit y2_200 = SMA2(gwalk, 200)
100 loops, best of 3: 5.53 ms per loop
100 loops, best of 3: 10.4 ms per loop

Puisque lfilter est une fonction de filtre à usage général, non dédiée à SMA, le temps d'exécution semble changer en fonction de la période. Les périodes plus courtes sont plus rapides que les pandas, mais les périodes plus longues sont plus lentes.

Mise en œuvre par instruction for (1)

Écrivons la formule de calcul SMA directement en utilisant l'instruction for. Bien sûr, il est évident qu'il sera lent s'il est laissé tel quel, alors comme le titre l'indique, utilisez numba pour l'accélérer.

@jit
def SMA3(x, period):
    y = np.zeros(len(x))
    for i in range(len(y)):
        for j in range(period):
            y[i] += x[i-j]
    return y/period
%timeit y3_20 = SMA3(gwalk, 20)
%timeit y3_200 = SMA3(gwalk, 200)
100 loops, best of 3: 3.07 ms per loop
10 loops, best of 3: 32.3 ms per loop

J'utilise l'instruction for, mais si la période est de 20 en raison de l'effet d'accélération de numba, c'est la plus rapide à ce jour. Cependant, comme elle est proportionnelle à la période, si elle est de 200, elle sera 10 fois plus lente, et ce sera la plus lente.

Mise en œuvre par instruction for (2)

La mise en œuvre finale est une méthode qui tire parti des caractéristiques du SMA. Puisque SMA ajoute simplement des échantillons, il ne calcule qu'en soustrayant l'ancienne valeur d'échantillon et en ajoutant la nouvelle valeur d'échantillon en utilisant le résultat du calcul d'un échantillon antérieur.

@jit
def SMA4(x, period):
    y = np.empty(len(x))
    y[:period-1] = np.nan
    y[period-1] = np.sum(x[:period])
    for i in range(period, len(x)):
        y[i] = y[i-1]+x[i]-x[i-period]
    return y/period

Nous ajouterons les échantillons jusqu'à ce que les échantillons soient prêts pour la période, mais après cela, nous ne devons ajouter que trois données. La vitesse d'exécution est la suivante.

%timeit y4_20 = SMA4(gwalk, 20)
%timeit y4_200 = SMA4(gwalk, 200)
1 loop, best of 3: 727 µs per loop
1000 loops, best of 3: 780 µs per loop

Il a le résultat le plus rapide de toute implémentation à ce jour. Le résultat était presque le même même si la période était prolongée.

Comme mentionné ci-dessus, en supposant l'accélération par numba, il a été constaté que la vitesse de SMA est assez élevée même si l'instruction for est utilisée.

Recommended Posts

À propos du code Python pour une moyenne mobile simple en supposant l'utilisation de Numba
Code pour vérifier le fonctionnement de Python Matplot lib
À propos des fonctionnalités de Python
Comparaison du code de moyenne mobile exponentielle (EMA) écrit en Python
À propos de la liste de base des bases de Python
J'ai comparé le temps de calcul de la moyenne mobile écrite en Python
Envelopper (partie de) la bibliothèque AtCoder en Cython pour une utilisation en Python
À propos de l'environnement virtuel de Python version 3.7
[Python3] Réécrire l'objet code de la fonction
Pandas du débutant, par le débutant, pour le débutant [Python]
[Python] Récupère le code de caractère du fichier
Conseils aux débutants en Python pour utiliser l'exemple Scikit-image pour eux-mêmes 6 Améliorer le code Python
[Python] Lire le code source de Bottle Part 2
L'histoire selon laquelle le coût d'apprentissage de Python est faible
Écrire une note sur la version python de python virtualenv
[Python] Lire le code source de Bottle Part 1
Traitement d'image? L'histoire du démarrage de Python pour
[Note] À propos du rôle du trait de soulignement "_" en Python
Convertir le code de caractère du fichier avec Python3
[Python] Calculez la valeur moyenne de la valeur de pixel RVB de l'objet
Décomposons les bases du code Python de TensorFlow
Récupérer le code retour d'un script Python depuis bat
Calculer le coefficient de régression d'une analyse de régression simple avec python
Utilisons la version Python du module API Confluence.
Utilisons les données ouvertes de "Mamebus" en Python
[Python] Utilisez l'API Face de Microsoft Cognitive Services
Un mémorandum sur la mise en œuvre des recommandations en Python
mémo python (pour moi-même): À propos de l'environnement de développement virtualenv
[Python] Code pour mesurer la lumière ambiante RVB de l'APDS9960
Code python de la méthode k-means super simple
À propos de Python for loop
le zen de Python
À propos de Python, pour ~ (plage)
Utilisez le hachage pour alléger le jugement de collision d'environ 1000 balles en Python (lié au nouveau virus corona)
Les personnes expérimentées qui utilisent principalement PHP parlent du 4ème jour de démarrage de Python (sous-processus)
Une implémentation Python simple de la méthode k-voisinage (k-NN)
Activer l'environnement virtuel Python de virtualenv pour Visual Studio Code
Vérifiez le fonctionnement de Python pour .NET dans chaque environnement
[python] Comment utiliser Matplotlib, une bibliothèque pour dessiner des graphiques
Prise en compte des décorateurs Python du type qui passe des variables
Je ne savais pas comment utiliser l'instruction [python] for
Je viens d'écrire le matériel original pour l'exemple de code python
Le processus de création et d'amélioration du code Python orienté objet
Conseils aux débutants en Python pour utiliser l'exemple Scikit-image par eux-mêmes
[Python] Les principales faiblesses et inconvénients de Google Colaboratory [Pour les débutants]
Google recherche la chaîne sur la dernière ligne du fichier en Python
Les personnes expérimentées qui utilisent principalement PHP parlent du 5ème jour après le démarrage de Python (sélénium) PHP vs Python
[Python] Comment utiliser l'instruction for. Une méthode d'extraction en spécifiant une plage ou des conditions.
Prise en charge de Fabric pour Python 3
À propos du module Python venv
Expliquez le code de Tensorflow_in_ROS
À propos de la fonction enumerate (python)
Mémo de code personnel Python
À propos de divers encodages de Python 3
2.x, 3.x code de caractères des séries python