我有以下函数,我希望从指定值的表中进行插值。诀窍在于,表格是以对数日志的方式定义的,因此log-log中各点之间的直线确实是指数级的。因此,我无法真正使用任何典型的scipy插值例程。
所以这就是我所拥有的:
PSD = np.array([[5.0, 0.001],
[25.0, 0.03],
[30.0, 0.03],
[89.0, 0.321],
[90.0, 1.0],
[260.0, 1.0],
[261.0, 0.03],
[359.0, 0.03],
[360.0, 0.5],
[520.0, 0.5],
[540.0, 0.25],
[780.0, 0.25],
[781.0, 0.03],
[2000.0, 0.03]])
def W_F(freq):
'''
A line connecting two points in a log-log plot are exponential
'''
w_f = []
for f in freq:
index = np.searchsorted(PSD[:,0], f)
if index <= 0:
w_f.append(PSD[:,1][0])
elif index + 1>= PSD.shape[0]:
w_f.append(PSD[:,1][-1])
x0 = PSD[:,0][index-1]
F0 = PSD[:,1][index-1]
x1 = PSD[:,0][index]
F1 = PSD[:,1][index]
w_f.append(F0*(f/x0)**(math.log(F1/F0)/math.log(x1/x0)))
return np.array(w_f)
我正在寻找一种更好,更清洁,“numpy-ish”的方式来实现这个
答案 0 :(得分:3)
最简单的方法是取PSD
的对数,然后使用SciPy插值函数:
logPSD = numpy.log(PSD)
logW_F = scipy.interpolate.interp1d(logPSD[:,0], logPSD[:,1])
W_F = numpy.exp(logW_F(numpy.log(f)))
这将为越界值抛出错误。为避免错误,您可以
将bounds_error=False
传递给interp1d()
函数,请参阅the documentation。
在PSD的开头和结尾添加一个条目,其中包含一个非常小且非常大的x值,以捕获所有可能的值。
作为使用interp1d()
的替代方法,可以对代码进行矢量化,但我只会出于某种原因这样做。