Интерполировать без зацикливания - PullRequest
0 голосов
/ 20 октября 2019

Скажем, массив sig:

sig = np.array([1,2,3,4,5])

Другой массив k, который состоит из индексов:

k = np.array([1,2,0,4])

Я хочу найти массив, который интерполирует междуs[k[i]-1] and s[k[i]] только если k[i]!= 0 and k[i] != len(k) т.е.

p=2
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])

Как мне сделать это без зацикливания на len(k) путем векторизации

Ожидается: result = array([1.66666667,3, 1, 4])

Потому что дляk = 0 and k =4 Я не интерполировал значения были возвращены как sig[0] and sig[3] соответственно

1 Ответ

0 голосов
/ 21 октября 2019

Для (очень) ограниченного количества случаев, таких как здесь, подход к векторизации такого кода состоит в построении линейной комбинации каждого случая и соответствующего вычисления.

Итак, установите векторы

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

Надеюсь, это поможет!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...