Вычисление массива numpy по значениям другого массива - PullRequest
0 голосов
/ 01 июля 2019

Мне нужно вычислить массив Z, имеющий массив D (только с использованием индексации, срезов и широковещания, без циклов):

D = [0, 0, 0, 0, 12, 36, 24, 24, 0, 0, 0, 0, 0, 0, 0, 12, 0, 0, 0, 36]

Z = [nan, nan, nan, nan, 12., 14.4, 15.36, 16.224, 16.224, 16.224, 16.224, 16.224, 16.224, 16.224, 16.224, 15.8016, 15.8016, 15.8016, 15.8016, 17.8214]

Правило # 1: перед первым ненулевым значением D (здесь индекс <4) => значения массива Z равны nan (здесь индексы от 0 до 3)

Правило № 2: первое ненулевое значение D (здесь индекс 4, значение 12) => массив Z получает значение Aпри этом индексе (12)

Правило № 3: Следуя правилу № 2, если D не равно 0 при индексе i => Z [i] = Z [i-1] + 0,1 * (D [i] - Z [i-1])

т.е.:

ind=4: D[4]=12 => Z[4]=12 (Rule#2)

ind=5: D[5]=36 => Z[5]=12 + 0.1 * (36 - 12) = 14.4

ind=6: D[6]=24 => Z[6]=14.4 + 0.1 * (24 - 14.4) = 15.36

ind=7: D[7]=24 => Z[7]=15.36 + 0.1 * (24 - 15.36) = 16.224

Правило № 4: Если D равно 0 (здесь индекс i = 8) => Z [i]= Z [i-1]

т.е.:

ind=8: D[8]=0 =>  D[8]=D[7]=16.224

1 Ответ

1 голос
/ 02 июля 2019

Я надеюсь, что это может помочь:

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)]
...