Dans l'analyse technique des données de séries chronologiques, il est courant de déplacer la fenêtre vers la moyenne et de trouver les valeurs maximale et minimale. Avec les pandas, vous pouvez facilement écrire en spécifiant la fenêtre de déplacement avec roulement et en utilisant les méthodes moyenne, max, min. Cet article est une note lorsque je cherchais un moyen plus rapide que les pandas.
Tout d'abord, créez une série chronologique de nombres aléatoires avec le tableau numpy et la série pandas comme indiqué ci-dessous.
import numpy as np
import pandas as pd
a = np.random.randint(100, size=100000)
s = pd.Series(a)
La moyenne dans la fenêtre mobile (dite moyenne mobile simple) peut être écrite comme suit en utilisant la méthode moyenne pour le roulement.
period=10 #période
%timeit smean = s.rolling(period).mean()
Temps d'exécution
100 loops, best of 3: 5.47 ms per loop
était. Viennent ensuite les valeurs maximum et minimum dans la fenêtre de déplacement.
%timeit smax = s.rolling(period).max()
%timeit smin = s.rolling(period).min()
100 loops, best of 3: 5.51 ms per loop
100 loops, best of 3: 5.53 ms per loop
Le temps d'exécution est presque le même que la moyenne mobile.
Puisque la moyenne mobile est un soi-disant filtre FIR, vous pouvez utiliser la fonction lfilter de scipy.
from scipy.signal import lfilter
%timeit amean = lfilter(np.ones(period)/period, 1, a)
Calculez comme un filtre FIR avec tous les poids définis sur 1 / période. Temps d'exécution
1000 loops, best of 3: 980 µs per loop
est devenu. C'est plus de 5 fois plus rapide que les pandas. Comme prévu, c'est scipy.
Maintenant, je veux trouver les valeurs maximum et minimum, mais il n'y a pas de fonction parfaite pour cela, et je pense que je peux utiliser order_filter. C'était une fonction scipy.signal.order_filter.html). Cette fonction est une fonction qui renvoie séquentiellement la valeur du rang spécifié dans la fenêtre spécifiée. Spécifiez le tableau de masque de la fenêtre dans le domaine d'argument et le rang dans le rang d'argument. Cependant, étant donné que la fenêtre cible sera centrée sur des échantillons de séries chronologiques, ne mettez 1 que dans la première moitié du tableau. Pour la valeur minimale, rang = 0 et pour la valeur maximale, rang = période-1.
from scipy.signal import order_filter
domain = np.concatenate((np.ones(period), np.zeros(period-1)))
%timeit amax = order_filter(a, domain, period-1)
%timeit amin = order_filter(a, domain, 0)
Le résultat de l'exécution est le suivant.
10 loops, best of 3: 102 ms per loop
10 loops, best of 3: 102 ms per loop
Cette fois, c'est presque 20 fois plus lent que les pandas. Même la fonction scipy ne fonctionnait pas. Après tout, c'est probablement parce qu'il est trié à chaque fois pour pouvoir être classé arbitrairement. Si vous souhaitez trouver les valeurs maximale et minimale, vous devez utiliser une fonction dédiée.
Recommended Posts