2016-08-09 1 views
3

Ich versuche, den prozentualen Rang von Daten nach Spalte innerhalb eines rollenden Fensters zu berechnen.Panda rollenden Fenster Perzentil Rang

test=pd.DataFrame(np.random.randn(20,3),pd.date_range('1/1/2000',periods=20),['A','B','C']) 

test 
Out[111]: 
        A   B   C 
2000-01-01 -0.566992 -1.494799 0.462330 
2000-01-02 -0.550769 -0.699104 0.767778 
2000-01-03 -0.270597 0.060836 0.057195 
2000-01-04 -0.583784 -0.546418 -0.557850 
2000-01-05 0.294073 -2.326211 0.262098 
2000-01-06 -1.122543 -0.116279 -0.003088 
2000-01-07 0.121387 0.763100 3.503757 
2000-01-08 0.335564 0.076304 2.021757 
2000-01-09 0.403170 0.108256 0.680739 
2000-01-10 -0.254558 -0.497909 -0.454181 
2000-01-11 0.167347 0.459264 -1.247459 
2000-01-12 -1.243778 0.858444 0.338056 
2000-01-13 -1.070655 0.924808 0.080867 
2000-01-14 -1.175651 -0.559712 -0.372584 
2000-01-15 -0.216708 -0.116188 0.511223 
2000-01-16 0.597171 0.205529 -0.728783 
2000-01-17 -0.624469 0.592436 0.0 
2000-01-18 0.259269 0.665585 0.126534 
2000-01-19 1.150804 0.575759 -1.335835 
2000-01-20 -0.909525 0.500366 2.120933 

Ich habe versucht, .rolling mit .apply zu verwenden, aber mir fehlt etwas.

pctrank = lambda x: x.rank(pct=True) 
rollingrank=test.rolling(window=10,centre=False).apply(pctrank) 

Für Spalte A der Endwert wäre der Prozentrang von -0,909525 innerhalb der Länge = 10 Fenster von 2000.01.11 bis 2000-01-20. Irgendwelche Ideen?

Antwort

3

Ihr Lambda erhält eine numpy Array, das kein .rank Methode hat — es Pandas des Series und DataFrame ist, die es haben. Sie können es so zu

ändern
pctrank = lambda x: pd.Series(x).rank(pct=True).iloc[-1] 

Oder könnten Sie rein numpy entlang der Linien von this SO answer verwenden:

def pctrank(x): 
    n = len(x) 
    temp = x.argsort() 
    ranks = np.empty(n) 
    ranks[temp] = (np.arange(n) + 1)/n 
    return ranks[-1] 
+0

Das ist perfekt, genau das, was ich suchte. Vielen Dank. Also habe ich es versäumt, x als Panda-Serie zu definieren, bevor ich rank() anwende. Kannst du erklären, warum mein Lambda eine Reihe erhält? .rolling() und .apply() sind beide Pandafunktionen, die auf einem Panda-Datenrahmen "Test" wirken? – user6435943

+0

* Warum erhält mein Lambda ein numpiges Array? * Ich weiß nicht warum; Ich weiß nur, dass der Fehler etwas wie "' numpy.darray' hat keine Methode 'rank'" sagt. 'Rollen' ist eine Methode der Pandas' Series' und 'DataFrame'. 'apply' hat mehrere verschiedene Inkarnationen. Sehen Sie sich die Dokumentation [split-apply-combine] (http://pandas.pydata.org/pandas-docs/stable/groupby.html) an. –