不循环插值
Interpolate without looping
假设一个数组 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]
对于像这里这样的(非常)有限的案例,向量化此类代码的方法是构建每个案例和相应计算的线性组合。
所以,设置向量
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. ]
希望对您有所帮助!
假设一个数组 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]
对于像这里这样的(非常)有限的案例,向量化此类代码的方法是构建每个案例和相应计算的线性组合。
所以,设置向量
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. ]
希望对您有所帮助!