Скользящий процент в пандах - PullRequest
0 голосов
/ 03 декабря 2018

Ниже - мой фрейм данных.Я пытаюсь вычислить 5-процентный ранг в процентах ATR.RollingPercentRank - мой желаемый результат.

       symbol         Day      time       ATR  RollingPercentRank
316356    SPY  11/29/2018  10:35:00  0.377880                 NaN
316357    SPY  11/29/2018  10:40:00  0.391092                 NaN
316358    SPY  11/29/2018  10:45:00  0.392983                 NaN
316359    SPY  11/29/2018  10:50:00  0.399685                 NaN
316360    SPY  11/29/2018  10:55:00  0.392716                 0.2
316361    SPY  11/29/2018  11:00:00  0.381445                 0.2
316362   AAPL  11/29/2018  11:05:00  0.387300                 NaN
316363   AAPL  11/29/2018  11:10:00  0.390570                 NaN
316364   AAPL  11/29/2018  11:15:00  0.381313                 NaN
316365   AAPL  11/29/2018  11:20:00  0.398182                 NaN
316366   AAPL  11/29/2018  11:25:00  0.377364                 0.6
316367   AAPL  11/29/2018  11:30:00  0.373627                 0.2

Начиная с 5-й строки, я хочу применить функцию процентного ранга ко всем 5 предыдущим значениям (с 1-го по 5-й ряд) ATR в группе.А что касается 6-й строки, я хочу снова применить функцию ранга ко всем 5 предыдущим значениям (от 2-й строки до 6-й строки) ATR.Я пробовал следующее, что дает «numpy.ndarray» объект не имеет атрибута «rank» ошибка.

df['RollingPercentRank'] = df.groupby(['symbol'])['ATR'].rolling(window=5,min_periods=5,center=False).apply(lambda x: x.rank(pct=True)).reset_index(drop=True)

1 Ответ

0 голосов
/ 03 декабря 2018

IIUC, поскольку я не получаю ожидаемый результат, который вы показали, но чтобы использовать rank, вам нужно pd.Series, а затем вам нужно только последнее значение этой процентной серии из 5 элементов, поэтому это будет:

print (df.groupby(['symbol'])['ATR']
         .rolling(window=5,min_periods=5,center=False)
         .apply(lambda x: pd.Series(x).rank(pct=True).iloc[-1]))

symbol  i     
AAPL    316362    NaN
        316363    NaN
        316364    NaN
        316365    NaN
        316366    0.2
        316367    0.2
SPY     316356    NaN
        316357    NaN
        316358    NaN
        316359    NaN
        316360    0.6
        316361    0.2

Поскольку x ix для массива numpy, можно получить тот же результат, используя дважды argsort и создать столбец reset_index вконец:

win_val = 5
df['RollingPercentRank'] = (df.groupby(['symbol'])['ATR']
                              .rolling(window=win_val,min_periods=5,center=False)
                              .apply(lambda x: x.argsort().argsort()[-1]+1)
                              .reset_index(level=0,drop=True)/win_val)

print (df)
       symbol         Day      time       ATR  RollingPercentRank

316356    SPY  11/29/2018  10:35:00  0.377880                 NaN
316357    SPY  11/29/2018  10:40:00  0.391092                 NaN
316358    SPY  11/29/2018  10:45:00  0.392983                 NaN
316359    SPY  11/29/2018  10:50:00  0.399685                 NaN
316360    SPY  11/29/2018  10:55:00  0.392716                 0.6
316361    SPY  11/29/2018  11:00:00  0.381445                 0.2
316362   AAPL  11/29/2018  11:05:00  0.387300                 NaN
316363   AAPL  11/29/2018  11:10:00  0.390570                 NaN
316364   AAPL  11/29/2018  11:15:00  0.381313                 NaN
316365   AAPL  11/29/2018  11:20:00  0.398182                 NaN
316366   AAPL  11/29/2018  11:25:00  0.377364                 0.2
316367   AAPL  11/29/2018  11:30:00  0.373627                 0.2
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...