2013-01-21 8 views
5

Ich bin neu in Python und der Pandas-Bibliothek, so entschuldigt, wenn dies eine triviale Frage ist. Ich versuche eine Zeitreihe über ein rollendes Fenster von N Tagen zu ordnen. Ich weiß, dass es eine Rangfunktion gibt, aber diese Funktion zählt die Daten über die gesamte Zeitreihe. Ich bin nicht in der Lage, eine rollende Rangfunktion zu finden. Hier ist ein Beispiel dafür, was ich zu tun versucht:Rang Daten über ein rollendes Fenster in Pandas DataFrame

  A 

01-01-2013 100 
02-01-2013 85 
03-01-2013 110 
04-01-2013 60 
05-01-2013 20 
06-01-2013 40 

Wenn ich die Daten über ein Rollfenster von 3 Tagen, Rang wollte sollte die Antwort sein:

  Ranked_A 

01-01-2013 NaN 
02-01-2013 Nan 
03-01-2013 1 
04-01-2013 3 
05-01-2013 3 
06-01-2013 2 

Gibt es ein eingebaute Funktion in Python, die dies tun können? Irgendein Vorschlag? Vielen Dank.

Antwort

3

Wenn Sie die Pandas built-in rank method (mit einigen zusätzlichen Semantik verwenden möchten, wie die aufsteigende Option), können Sie eine einfache Funktion Wrapper für sie

def rank(array): 
    s = pd.Series(array) 
    return s.rank(ascending=False)[len(s)-1] 

erstellen, die dann als benutzerdefinierte Rollfensterfunktion verwendet werden kann.

pd.rolling_apply(df['A'], 3, rank) 

die Ausgänge

Date 
01-01-2013 NaN 
02-01-2013 NaN 
03-01-2013  1 
04-01-2013  3 
05-01-2013  3 
06-01-2013  2 

(Ich bin die df Datenstruktur von Rutger Antwort vorausgesetzt) ​​

+0

Ihnen sehr für Ihre Hilfe danken. Das ist sehr hilfreich. – FrankDR

+1

das ist wirklich langsam. Ich glaube, dass es eine eingebaute Möglichkeit gab, dies in Pandas 1.18 zu tun, aber sie wurden in .20.xx beseitigt. Weißt du, wie man das macht? ? – Adam

2

Sie können eine benutzerdefinierte Funktion für ein Rolling-Fenster in Pandas schreiben. numpy des argsort Unter Verwendung von() in dieser Funktion können Sie geben den Rang innerhalb des Fensters:

import pandas as pd 
import StringIO 

testdata = StringIO.StringIO(""" 
Date,A 
01-01-2013,100 
02-01-2013,85 
03-01-2013,110 
04-01-2013,60 
05-01-2013,20 
06-01-2013,40""") 

df = pd.read_csv(testdata, header=True, index_col=['Date']) 

rollrank = lambda data: data.size - data.argsort().argsort()[-1] 

df['rank'] = pd.rolling_apply(df, 3, rollrank) 

print df 

Ergebnisse in:

   A rank 
Date     
01-01-2013 100 NaN 
02-01-2013 85 NaN 
03-01-2013 110  1 
04-01-2013 60  3 
05-01-2013 20  3 
06-01-2013 40  2