Bei der technischen Analyse von Zeitreihendaten ist es üblich, das Fenster auf Mittelwert zu verschieben und die Maximal- und Minimalwerte zu ermitteln. Mit Pandas können Sie einfach schreiben, indem Sie das Verschiebefenster mit Rollen angeben und die Methoden mean, max, min verwenden. Dieser Artikel ist eine Notiz, als ich nach einem schnelleren Weg als Pandas suchte.
Erstellen Sie zunächst eine Zeitreihe von Zufallszahlen mit numpy array und pandas Series, wie unten gezeigt.
import numpy as np
import pandas as pd
a = np.random.randint(100, size=100000)
s = pd.Series(a)
Der Durchschnitt im gleitenden Fenster (sogenannter einfacher gleitender Durchschnitt) kann unter Verwendung der mittleren Methode zum Rollen wie folgt geschrieben werden.
period=10 #Zeitraum
%timeit smean = s.rolling(period).mean()
Ausführungszeit
100 loops, best of 3: 5.47 ms per loop
war. Als nächstes werden die Maximal- und Minimalwerte im Verschiebefenster angezeigt.
%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
Die Ausführungszeit entspricht fast dem gleitenden Durchschnitt.
Da der gleitende Durchschnitt ein sogenannter FIR-Filter ist, können Sie die Filterfunktion von scipy verwenden.
from scipy.signal import lfilter
%timeit amean = lfilter(np.ones(period)/period, 1, a)
Berechnen Sie als FIR-Filter, wobei alle Gewichte auf 1 / Periode eingestellt sind. Ausführungszeit
1000 loops, best of 3: 980 µs per loop
ist geworden. Es ist mehr als fünfmal schneller als Pandas. Wie erwartet ist es scipy.
Jetzt möchte ich die Maximal- und Minimalwerte finden, aber dafür gibt es keine perfekte Funktion, und die, die als verwendbar erscheint, ist order_filter. Es war eine scipy.signal.order_filter.html) Funktion. Diese Funktion gibt nacheinander den Wert des angegebenen Ranges im angegebenen Fenster zurück. Geben Sie das Maskenarray des Fensters in der Argumentdomäne und den Rang im Argumentrang an. Da das Zielfenster jedoch auf Zeitreihenabtastungen zentriert ist, setzen Sie 1 nur in die erste Hälfte des Arrays. Für den Minimalwert ist Rang = 0 und für den Maximalwert Rang = Periode-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)
Das Ausführungsergebnis ist wie folgt.
10 loops, best of 3: 102 ms per loop
10 loops, best of 3: 102 ms per loop
Diesmal ist es fast 20 Mal langsamer als Pandas. Sogar die Scipy-Funktion funktionierte nicht. Schließlich liegt es wahrscheinlich daran, dass es jedes Mal so sortiert wird, dass es willkürlich eingestuft werden kann. Wenn Sie die Maximal- und Minimalwerte ermitteln möchten, sollten Sie eine spezielle Funktion verwenden.
Recommended Posts