Wie berechnet man den gleitenden Durchschnitt in Python 3?

8

Sagen wir, ich habe eine Liste:

%Vor%

Ich möchte eine Funktion erstellen, die den gleitenden n-Tages-Durchschnitt berechnet. Wenn also n 5 wäre, würde ich meinen Code die ersten 1-5 berechnen lassen, sie addieren und den Durchschnitt finden, was 3.0 wäre, dann gehe ich zu 2-6 über und berechne den Durchschnitt, was 4.0 wäre. dann 3-7, 4-8, 5-9, 6-10.

Ich möchte nicht die ersten n-1 Tage berechnen, also ab dem n-ten Tag zählt es die vorherigen Tage.

%Vor%

Dies scheint auszudrucken, was ich will:

%Vor%

Ich weiß jedoch nicht, wie ich die Zahlen in diesen Listen berechnen soll. Irgendwelche Ideen?

    
Kara 14.02.2013, 21:05
quelle

5 Antworten

18

In einer alten Version der Python-Dokumente gibt es einen tollen Gleitfenster-Generator mit itertools Beispiele :

%Vor%

Die Verwendung Ihrer gleitenden Durchschnittswerte ist trivial:

%Vor%

Wenn Sie dies gegen Ihre Eingabe (das Zuordnen der Strings zu Ganzzahlen) ausführen, erhalten Sie:

%Vor%

Um None die ersten n - 1 Iterationen für 'incomplete' Sets zurückzugeben, erweitern Sie einfach die moving_averages Funktion etwas:

%Vor%     
Martijn Pieters 14.02.2013, 21:07
quelle
4

Während ich Martijns Antwort darauf mag, wie George, habe ich mich gefragt, ob das nicht schneller wäre, wenn man es benutzt eine laufende Summierung, anstatt die sum() immer wieder auf fast die gleichen Zahlen anzuwenden.

Auch die Idee, None -Werte während der Hochlaufphase als Standard zu haben, ist interessant. In der Tat könnte es viele verschiedene Szenarien geben, die man sich für gleitende Durchschnitte vorstellen könnte. Teilen wir die Berechnung der Durchschnittswerte in drei Phasen:

  1. Ramp Up: Starten von Iterationen, bei denen die aktuelle Iteration & lt; Fenstergröße
  2. Stetiger Fortschritt: Wir haben genau die Fenstergröße Anzahl der Elemente, um eine normale average := sum(x[iteration_counter-window_size:iteration_counter])/window_size zu berechnen
  3. Ramp Down: Am Ende der Eingabedaten könnten wir eine weitere window_size - 1 "durchschnittliche" Zahl zurückgeben.

Hier ist eine Funktion, die

akzeptiert
  • Beliebige Iterables (Generatoren sind in Ordnung) als Eingabe für Daten
  • Beliebige Fenstergrößen & gt; = 1
  • Parameter zum Ein- / Ausschalten der Produktion von Werten während der Phasen für Ramp Up / Down
  • Callback-Funktionen für diese Phasen, um zu steuern, wie Werte erzeugt werden. Dies kann verwendet werden, um einen Standard (z. B. None ) oder Teildurchschnittswerte
  • bereitzustellen

Hier ist der Code:

%Vor%

Es scheint ein bisschen schneller zu sein als Martijns Version - die jedoch viel eleganter ist. Hier ist der Testcode:

%Vor%

Und die Ausgabe:

%Vor%

Die ursprüngliche Frage kann jetzt mit diesem Funktionsaufruf gelöst werden:

%Vor%

Die Ausgabe:

%Vor%     
cfi 18.02.2013 18:15
quelle
1

Verwenden Sie die Funktionen sum und map .

%Vor%

Die Funktion map in Python 3 ist im Grunde eine faule Version von dieser:

%Vor%

Ich bin sicher, Sie können erraten, was die Funktion sum macht.

    
Volatility 14.02.2013 21:07
quelle
1

Ein Ansatz, der die Neuberechnung von Zwischensummen vermeidet.

%Vor%

Druckergebnis

%Vor%

mach das läuft (int (v)) .. dann .. repr (runsumlist [k] - runsumlist [k-5]) / 5) Wenn Sie Zahlen um eine Zeichenfolge herumtragen ..

Alt ohne global:

%Vor%

Achten Sie darauf, floatende Mathematik zu verwenden, auch wenn Sie Werte als Ganzzahlen eingeben

%Vor%     
agentp 14.02.2013 22:04
quelle
0

Es gibt eine andere Lösung, die ein itertools rezept pairwise() erweitert. Sie können dies auf nwise() erweitern, was Ihnen das gleitende Fenster gibt (und funktioniert, wenn das iterable ein Generator ist):

%Vor%

Während ein relativ hoher Setup-Aufwand für kurze iterable s diese Kosten reduziert, je länger der Datensatz ist. Dies verwendet sum() , aber der Code ist einigermaßen elegant:

%Vor%     
AChampion 26.11.2016 14:59
quelle

Tags und Links