两个二维数组的线性插值

5
在之前的一个问题中(如何在2-D数组上使用numpy.interp的最快方法),有人询问了实现以下操作的最快方式:
np.array([np.interp(X[i], x, Y[i]) for i in range(len(X))])

假设XY是具有许多行的矩阵,因此for循环的成本很高。在这种情况下,有一个很好的解决方案可以避免for循环(参见上面链接的答案)。

我面临着一个非常类似的问题,但是我不确定在这种情况下是否可以避免使用for循环:

np.array([np.interp(x, X[i], Y[i]) for i in range(len(X))])

换句话说,我想使用线性插值来上采样存储在两个矩阵 XY 的行中的大量信号。我希望能够在numpy或scipy中找到一个函数(如scipy.interpolate.interp1d),通过广播语义支持此操作,但到目前为止似乎找不到这样的函数。
其他要点: - 如果有帮助的话,我的应用程序中预排序了行 X[i]x。此外,在我的情况下,len(x) 要比 len(X[i]) 大得多。 - 函数 scipy.signal.resample 几乎可以实现我想要的功能,但它不使用线性插值...
1个回答

5
这是一种矢量化方法,直接实现线性插值。首先,对于每个x和每个i,j值,计算表示区间(X[i, j],X[i, j+1])左侧有多少比例的权重w
  • 如果整个区间都在x的左侧,则该区间的权重为1。
  • 如果子区间没有在左侧,则权重为0。
  • 否则,权重是介于0到1之间的数字,表示该区间左侧的比例。
然后,PL插值的值计算为Y[i, 0]加上差异dY[i, j]乘以相应权重的总和。其逻辑是从一个区间到另一个区间跟随插值器变化的大小。差异dY = np.diff(Y, axis=1)显示它在整个区间内的变化程度。通过权重的乘法按比例分配这种变化。

设置,使用一些小型数据数组

import numpy as np
X = np.array([[0, 2, 5, 6, 9], [1, 3, 4, 7, 8]])
Y = np.array([[3, 5, 2, 4, 1], [8, 6, 9, 5, 4]])
x = np.linspace(1, 8, 20)

计算

dX = np.diff(X, axis=1)
dY = np.diff(Y, axis=1)
w = np.clip((x - X[:, :-1, None])/dX[:, :, None], 0, 1)
y = Y[:, [0]] + np.sum(w*dY[:, :, None], axis=1)

演示

此处仅用来展示插值的正确性。蓝色点表示原始数据,红色点表示计算得到的数据。

import matplotlib.pyplot as plt
plt.plot(x, y[0], 'ro')
plt.plot(X[0], Y[0], 'bo')
plt.plot(x, y[1], 'rd')
plt.plot(X[1], Y[1], 'bd')
plt.show()

PL interpolants


这假设(X,Y)的所有元素长度相同:\ - jessexknight

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接