[英]Panda rolling window percentile rank
我正在嘗試在滾動窗口中按列計算數據的百分位排名。
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.832100
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
我嘗試將 .rolling 與 .apply 一起使用,但我遺漏了一些東西。
pctrank = lambda x: x.rank(pct=True)
rollingrank=test.rolling(window=10,centre=False).apply(pctrank)
對於 A 列,最終值將是從 2000-01-11 到 2000-01-20 的 length=10 窗口內的百分位等級 -0.909525。 有什么想法嗎?
你的 lambda 接收一個 numpy 數組,它沒有.rank
方法——它是DataFrame
的Series
和DataFrame
有它。 您可以因此將其更改為
pctrank = lambda x: pd.Series(x).rank(pct=True).iloc[-1]
或者你可以按照這個 SO 答案的思路使用純 numpy :
def pctrank(x):
n = len(x)
temp = x.argsort()
ranks = np.empty(n)
ranks[temp] = (np.arange(n) + 1) / n
return ranks[-1]
最簡單的選擇是做這樣的事情: from scipy import stats 200 是窗口大小
數據集[名稱] = 數據集[名稱].rolling(200).apply(lambda x: stats.percentileofscore(x, x[-1]))
如果您只需要最后一次觀察的排名,就像滾動應用的情況一樣,您可以使用:
def pctrank(x):
i = x.argsort().argmax() + 1
n = len(x)
return i/n
時間大約快兩倍
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.