nan in interp1d scipy
我有以下代码,正在使用interp1d在python中进行处理,看来interp1d的输出乘以查询点数得出的数组起始值为
1 2 3 4 5 6 | Freq_Vector = np.arange(0,22051,1) Freq_ref = np.array([20,25,31.5,40,50,63,80,100,125,160,200,250,315,400,500,630,750,800,1000,1250,1500,1600,2000,2500,3000,3150,4000,5000,6000,6300,8000,9000,10000,11200,12500,14000,15000,16000,18000,20000]) W_ref=-1*np.array([39.6,32,25.85,21.4,18.5,15.9,14.1,12.4,11,9.6,8.3,7.4,6.2,4.8,3.8,3.3,2.9,2.6,2.6,4.5,5.4,6.1,8.5,10.4,7.3,7,6.6,7,9.2,10.2,12.2,10.8,10.1,12.7,15,18.2,23.8,32.3,45.5,50]) if FreqVector[-1] > Freq_ref[-1]: Freq_ref[-1] = FreqVector[-1] WdB = interpolate.interp1d(Freq_ref,W_ref,kind='cubic',axis=-1, copy=True, bounds_error=False, fill_value=np.nan)(FreqVector) |
WdB的前20个值是:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | 00000 = {float64} nan 00001 = {float64} nan 00002 = {float64} nan 00003 = {float64} nan 00004 = {float64} nan 00005 = {float64} nan 00006 = {float64} nan 00007 = {float64} nan 00008 = {float64} nan 00009 = {float64} nan 00010 = {float64} nan 00011 = {float64} nan 00012 = {float64} nan 00013 = {float64} nan 00014 = {float64} nan 00015 = {float64} nan 00016 = {float64} nan 00017 = {float64} nan 00018 = {float64} nan 00019 = {float64} nan 00020 = {float64} -39.6 00021 = {float64} -37.826313148 |
以下是maltab中前20个值的输出:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | -58.0424562952059 -59.2576965087483 -60.1150845850336 -60.6367649499501 -60.8448820293863 -60.7615802492306 -60.4090040353715 -59.8092978136973 -58.9846060100965 -57.9570730504576 -56.7488433606689 -55.3820613666188 -53.8788714941959 -52.2614181692886 -50.5518458177851 -48.7722988655741 -46.9449217385440 -45.0918588625830 -43.2352546635798 -41.3972535674226 -39.6000000000000 -37.8656383872004 |
我该如何避免这种情况,而实际上却拥有与interp1d相似的真实值?
我不知道确切的原因,但是当查看绘制的数据时,拟合实际上起作用。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | from scipy import interpolate import numpy as np from matplotlib import pyplot as plt Freq_Vector = np.arange(0,22051.0,1) Freq_ref = np.array([20,25,31.5,40,50,63,80,100,125,160,200,250,315,\ 400,500,630,750,800,1000,1250,1500,1600,2000,2500,3000,3150,\ 4000,5000,6000,6300,8000,9000,10000,11200,12500,14000,15000,\ 16000,18000,20000]) W_ref=-1*np.array([39.6,32,25.85,21.4,18.5,15.9,14.1,12.4,11,\ 9.6,8.3,7.4,6.2,4.8,3.8,3.3,2.9,2.6,2.6,4.5,5.4,6.1,8.5,10.4,7.3,7,\ 6.6,7,9.2,10.2,12.2,10.8,10.1,12.7,15,18.2,23.8,32.3,45.5,50]) if Freq_Vector[-1] > Freq_ref[-1]: Freq_ref[-1] = Freq_Vector[-1] WdB = interpolate.interp1d(Freq_ref.tolist(),W_ref.tolist(),\ kind='cubic', bounds_error=False)(Freq_Vector) plt.plot(Freq_ref,W_ref,'..',color='black',label='Reference') plt.plot(Freq_ref,W_ref,'-.',color='blue',label='Interpolated') plt.legend() |
该图如下所示:
插值实际上正在发生,但是拟合效果不理想。但是,如果您打算拟合数据,那么为什么不使用样条插值器呢?仍然是立方的,但不太容易发生过载。
1 | interpolate.InterpolatedUnivariateSpline(Freq_ref.tolist(),W_ref.tolist())(Freq_Vector) |
数据和绘图非常顺利。
1 2 3 4 | WdB Out[34]: array([-114.42984432, -108.43602531, -102.72381906, ..., -50.00471866, -50.00236016, -50. ]) |
因为您给它的样本点集(
并且由于您要求对
这不同于Matlab的默认值,后者使用请求的插值方法(docs)进行插值。
话虽这么说,我会谨慎地将Matlab(或任何程序)的默认外推值称为"实际值",因为外推可能非常困难并且容易产生异常行为。对于您引用的值,Matlab的
外推表示
话虽如此,如果您想向