2013-01-21 13 views
5

Sono nuovo in Python e nella libreria di Pandas, quindi scusa se questa è una domanda banale. Sto cercando di classificare un Timeseries su una finestra a rotazione di N giorni. So che esiste una funzione di classificazione, ma questa funzione classifica i dati su tutti i tempi. Non riesco a trovare una funzione di rango rotabile. Ecco un esempio di quello che sto cercando di fare:classifica dati su una finestra a rotazione in panda 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 

Se avessi voluto classificare i dati di più di una finestra a rotazione di 3 giorni, la risposta dovrebbe essere:

  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 

C'è un funzione built-in in Python che può fare questo? Qualche suggerimento? Mille grazie.

risposta

3

Se si desidera utilizzare la Panda built-in rank method (con alcune semantiche aggiuntive, come ad esempio l'opzione ascendente), è possibile creare un semplice involucro funzione per esso

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

che può quindi essere utilizzato come una funzione rolling-finestra personalizzata.

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

quali uscite

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 

(sto assumendo la struttura di dati df dalla risposta di Rutger)

+0

La ringrazio molto per il vostro aiuto. Questo è molto utile. – FrankDR

+1

questo è veramente lento. Credo che ci sia un modo per farlo in Panda 1.18 ma se ne sono sbarazzati in .20.xx conosci un modo nativo per fare questo ? – Adam

2

È possibile scrivere una funzione personalizzata per una finestra a rotazione in Panda. Utilizzando argsort di NumPy() in quella funzione può darvi il rango all'interno della finestra:

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 

risultati 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