Обновить: не уверен, что это возможно без какой-либо формы цикла , но np.where
здесь не работает. Если ответ: "вы не можете", то пусть будет так. Если это можно сделать, оно может использовать что-то из scipy.signal
.
Я хотел бы векторизовать цикл в коде ниже, но не знаю, как из-за рекурсивного характера вывода.
Прогулка - хотя из моей текущей настройки:
Возьмите стартовую сумму (1 миллион долларов США) и ежеквартальное распределение доллара (5000 долларов США):
dist = 5000.
v0 = float(1e6)
Сгенерировать некоторые случайные выходы безопасности/счета (десятичная форма) при ежемесячной частоте:
r = pd.Series(np.random.rand(12) * .01,
index=pd.date_range('2017', freq='M', periods=12))
Создайте пустую серию, в которой будут храниться месячные значения учетной записи:
value = pd.Series(np.empty_like(r), index=r.index)
Добавьте "начальный месяц" в value
. Эта метка будет содержать v0
.
from pandas.tseries import offsets
value = (value.append(Series(v0, index=[value.index[0] - offsets.MonthEnd(1)]))
.sort_index())
Цикл, который я бы хотел избавиться, находится здесь:
for date in value.index[1:]:
if date.is_quarter_end:
value.loc[date] = value.loc[date - offsets.MonthEnd(1)] \
* (1 + r.loc[date]) - dist
else:
value.loc[date] = value.loc[date - offsets.MonthEnd(1)] \
* (1 + r.loc[date])
Комбинированный код:
import pandas as pd
from pandas.tseries import offsets
from pandas import Series
import numpy as np
dist = 5000.
v0 = float(1e6)
r = pd.Series(np.random.rand(12) * .01, index=pd.date_range('2017', freq='M', periods=12))
value = pd.Series(np.empty_like(r), index=r.index)
value = (value.append(Series(v0, index=[value.index[0] - offsets.MonthEnd(1)])).sort_index())
for date in value.index[1:]:
if date.is_quarter_end:
value.loc[date] = value.loc[date - offsets.MonthEnd(1)] * (1 + r.loc[date]) - dist
else:
value.loc[date] = value.loc[date - offsets.MonthEnd(1)] * (1 + r.loc[date])
В psuedocode то, что делает цикл, это просто:
for each date in index of value:
if the date is not a quarter end:
multiply previous value by (1 + r) for that month
if the date is a quarter end:
multiply previous value by (1 + r) for that month and subtract dist
Проблема заключается в том, что в настоящее время я не вижу, как векторизация возможна, поскольку последовательное значение зависит от того, было ли распределение сделано за предыдущий месяц. Я получаю желаемый результат, но довольно неэффективно для более высоких частотных данных или больших периодов времени.