内插而不循环

时间:2019-10-20 16:07:31

标签: python numpy vectorization

让我们说一个数组信号:

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

由索引组成的另一个数组k:

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

我想找到一个仅在s[k[i]-1] and s[k[i]]即{p>

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

1 个答案:

答案 0 :(得分:0)

对于这种情况(数量非常有限),矢量化此类代码的一种方法是建立每种情况与相应计算的线性组合。

因此,设置向量

  • 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))

请注意-通过上面设置的betagamma-第二和第三种情况的计算可以合并。另外,我们在这里需要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.        ]

希望有帮助!