两个2D阵列的线性插值

时间:2018-04-08 01:43:18

标签: numpy scipy interpolation numpy-broadcasting

在上一个问题(fastest way to use numpy.interp on a 2-D array)中,有人要求以最快的方式实施以下内容:

X

假设Ynp.array([np.interp(x, X[i], Y[i]) for i in range(len(X))]) 是具有许多行的矩阵,因此for循环成本很高。在这种情况下有一个很好的解决方案可以避免for循环(参见上面的链接答案)。

我遇到了一个非常类似的问题,但我不清楚在这种情况下是否可以避免for循环:

X

换句话说,我想使用线性插值来对存储在两个矩阵YX[i]的行中的大量信号进行上采样。 我希望在numpy或scipy中找到一个函数(scipy.interpolate.interp1d),它通过广播语义来支持这个操作,但到目前为止我似乎找不到它。

其他要点:

  • 如果有帮助,行xlen(x)会在我的应用程序中预先排序。另外,在我的情况下,len(X[i])比{{1}}大一点。

  • 函数scipy.signal.resample几乎可以实现我想要的功能,但它不会使用线性插值...

1 个答案:

答案 0 :(得分:1)

这是一种直接实现线性插值的矢量化方法。首先,对于每个x值和每个i,j计算权重w,表示在x的左边有多少间隔(X [i,j],X [i,j + 1])。

  • 如果整个区间在x的左侧,则该区间的权重为1.
  • 如果子区间都不在左侧,则权重为0
  • 否则,权重是介于0和1之间的数字,表示该区间在x左侧的比例。

然后将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