Я надеюсь, что это может помочь:
def function_needed(D,alpha):
#Rule 1
Z=np.zeros(len(D))
idx=(np.array(D)!=0).argmax(axis=0)
Z[:idx] = np.NaN
#Rule 2
Z[idx]=D[idx]
#Rule 3
x=np.array(D)[np.nonzero(np.array(D))]
n = len(x)
y_1 = Z[idx]
pot = (1-alpha)**np.arange(n-1, -1, -1)
y = alpha*np.cumsum(pot * x)/pot+y_1*(1-alpha)**np.arange(1, n+1)
Z[np.nonzero(D)]=y
#Rule 4
mask =(Z==0)
idx = np.where(~mask,np.arange(mask.shape[0]),0)
Z=Z[np.maximum.accumulate(idx,axis=0, out=idx)]
return Z
testing=function_needed(D,0.1)
Я разработал функцию под названием function_needed, чтобы создать все правила один раз. Это объяснение шаг за шагом
Правило 1
1- Создать массив с 0 того же размера, что и исходный массив D
Z=np.zeros(len(D))
2- Получить индекс первого ненулевого значения
idx=(np.array(D)!=0).argmax(axis=0)
3- Поместить NaN во все значения до первого ненулевого значения
Z[:idx] = np.NaN
Правило 2
1 - заполнить Z первым ненулевым требованием по индексу первого ненулевого значения D
Z[idx]=D[idx]
Правило 3
Новый расчет Z выполняется только при ненулевом спросе
1- Создать X массив, соответствующий D ненулевой
x=np.array(D)[np.nonzero(np.array(D))]
2- Если мы рассмотрим Y, то расчет, предложенный в правиле 3 для ненулевого спроса. Заметим, что рекурсивно каждый элемент Y задается следующей формулой
изображение формулы
где y_1 - первое ненулевое значение
n = len(x)
y_1 = Z[idx]
pot = (1-alpha)**np.arange(n-1, -1, -1)
y = alpha*np.cumsum(pot * x)/pot+y_1*(1-alpha)**np.arange(1, n+1)
Z[np.nonzero(D)]=y
На этой стадии Z равно
Z
Правило 4
Заменить 0 значений, полученных на предыдущем шаге, на первое нижнее ненулевое значение. Это то, что мы называем заполнением вперед. Для этого:
mask =(Z==0)
idx = np.where(~mask,np.arange(mask.shape[0]),0)
Z=Z[np.maximum.accumulate(idx,axis=0, out=idx)]