Вычислить * прокат * максимальная просадка панд серии

Это'Довольно легко написать функцию, которая вычисляет максимальную просадку временного ряда. Нужно немного подумать, чтобы написать это вO(n) время вместоO(n^2) время. Но это'не так уж и плохо. Это будет работать:

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt

def max_dd(ser):
    max2here = pd.expanding_max(ser)
    dd2here = ser - max2here
    return dd2here.min()

Позволять's, чтобы поиграть в короткую серию:

np.random.seed(0)
n = 100
s = pd.Series(np.random.randn(n).cumsum())
s.plot()
plt.show()

Как и ожидалось,max_dd(s) в итоге показывает что-то прямо около -17,6. Хорошо, отлично, грандиозно. Теперь скажи мнеЯ заинтересован в расчете скользящей просадки этой серии. То есть для каждого шага я хочу вычислить максимальную просадку из предыдущей подсерии заданной длины. Это легко сделать с помощьюpd.rolling_apply, Это работает так:

rolling_dd = pd.rolling_apply(s, 10, max_dd, min_periods=0)
df = pd.concat([s, rolling_dd], axis=1)
df.columns = ['s', 'rol_dd_10']
df.plot()

Это работает отлично. Но это чувствуется очень медленно. Есть ли в пандах или другом инструментарии особенно удобный алгоритм, чтобы сделать это быстро? Я сделал попытку написать что-то сделанное на заказ: он отслеживает все виды промежуточных данных (местоположения наблюдаемых максимумов, местоположения ранее обнаруженных просадок), чтобы сократить множество избыточных вычислений. Это экономит некоторое время, но не очень много, и не так много, как должно быть возможно.

Я думаю это's из-за всех накладных расходов зацикливания в Python / Numpy / Pandas. Но я'В настоящее время я недостаточно владею Cython, чтобы действительно знать, как начать атаку с этой точки зрения. Я надеялся, что кто-то пробовал это раньше. Или, может быть, кто-то захочет посмотреть на меня?ручной работы" код и будьте готовы помочь мне преобразовать его в Cython.

Редактировать: Для тех, кто хочет просмотреть все функции, упомянутые здесь (и некоторые другие!), Посмотрите на записную книжку iPython по адресу:http://nbviewer.ipython.org/gist/8one6/8506455

Он показывает, как соотносятся некоторые подходы к этой проблеме, проверяет, дают ли они одинаковые результаты, и показывает время их выполнения на данных разных размеров.

Если кому-то интересно, тосделанный на заказ» Алгоритм, на который я ссылался в своем посте,rolling_dd_custom, Я думаю, что это может быть очень быстрое решение, если оно реализовано на Cython.

Ответы на вопрос(4)

Ваш ответ на вопрос