Для (очень) ограниченного количества случаев, таких как здесь, подход к векторизации такого кода состоит в построении линейной комбинации каждого случая и соответствующего вычисления.
Итак, установите векторы
alpha = (k == 0)
для сопоставления с первым регистром, beta = (k > 0)
для сопоставления со вторым регистром и gamma = (k < len(k))
для сопоставления с третьим регистром.
Затем создайте правильную линейную комбинацию, такую как:
alpha * sig[k] + beta * sig[k-1] + gamma * (sig[k] - sig[k-1] * (p - np.roll(k, 1)) / (k - np.roll(k, 1))
Обратите внимание, что - кстати, beta
и gamma
настроены выше - вычисления второго и третьегослучаи могут быть объединены. Кроме того, нам нужно np.roll
здесь, чтобы получить правильные k[i-1]
.
Окончательное решение, сведенное к одной строчке, выглядит так:
import numpy as np
# Inputs
sig = np.array([1, 2, 3, 4, 5])
k = np.array([1, 2, 0, 4])
p = 2
# Original solution using loop
result = np.zeros(len(k))
for i in range(len(k)):
if(k[i] == 0):
result[i] = sig[k[i]]
elif(k[i] == len(k)):
result[i] = sig[k[i] -1]
else:
result[i] = sig[k[i] -1] + (sig[k[i]] - sig[k[i]-1])*(p - k[i-1])/(k[i] - k[i-1])
# Vectorized solution
res = (k == 0) * sig[k] + (k > 0) * sig[k-1] + (k < len(k)) * (sig[k] - sig[k-1]) * (p - np.roll(k, 1)) / (k - np.roll(k, 1))
# Outputs
print('Original solution using loop:\n ', result)
print('Vectorized solution:\n ', res)
Выходы идентичны:
Original solution using loop:
[1.66666667 3. 1. 4. ]
Vectorized solution:
[1.66666667 3. 1. 4. ]
Надеюсь, это поможет!