【问题标题】:Why does interp1d in scipy give a NaN when the first 2 values of the x-array are identical? (fill_value = 0)当 x 数组的前 2 个值相同时,为什么 scipy 中的 interp1d 会给出 NaN? (填充值 = 0)
【发布时间】:2013-09-30 16:40:11
【问题描述】:
import numpy as np
from scipy.interpolate import interp1d

x = np.array([ 0,  0,   0,  0,   0,  30])
time = np.array([ 5,  5,  10,  10,  10,  20])

intx = interp1d(time,x,'linear', 0, True, False, 0)
print intx([4,5,5,6,10,11,20, 20.0001])

>>> [  0.  nan  nan   0.   0.   3.  30.   0.]

如您所见,在所有情况下,除了时间值 == 第一对值之外,插值器返回一个实数。

我知道 numpy.unique(),这只是一个学术问题。这是在 iPython 中运行的 Anaconda Python 2.7。

谢谢!

【问题讨论】:

    标签: python numpy scipy interpolation


    【解决方案1】:

    在上述情况下,我建议只为 Y 变量采样点。例如。考虑以下几点。

    x= [275, 275]
    y= [120, 120]
    

    以上点代表一条平行于 Y 轴的线。因此,线的斜率是不确定的。因此,您可以在此处仅为 Y 变量采样点,并为每个变量复制 X 变量的值。您会发现下面的图很直观。
    图 1 -

    情节 2 -

    【讨论】:

      【解决方案2】:

      您的问题是您正在尝试对区间外的点进行插值,这会导致scipy.interpolate.interp1d 在尝试计算两点之间的斜率时启动RuntimeWarning(它发生在 interpolate.py 中的第 416 行附近):

      slope = (y_hi - y_lo) / (x_hi - x_lo)[:, None]
      

      查看在区间内移动点时会发生什么:

      >>> import numpy as np
      >>> from scipy.interpolate import interp1d
      >>> x = np.array([ 5,  5,  10,  10,  10,  20])
      >>> y = np.array([ 0,  0,   0,  0,   0,  30])
      >>> X = np.array([5.1,5.1,5.1,6,10,11,20, 19.999])
      >>> f = interp1d(x,y,'linear', 0, True, False, 0)
      >>> Y = f(X)
       [  0.      0.      0.      0.      0.      3.     30.     29.997]
      

      如果你绘制它,你会发现一切都是有道理的:

      interp1d 是这样工作的:

      1. 您将xy 传递给interp1d,它会创建一个f 可调用方法
      2. 然后你传递新的x_new 值来评估f 并执行以下步骤:

        • 在原始数据中查找要插入的值的位置。

          >>> x_new_indices = np.searchsorted(x, X)
          
        • 剪辑 x_new_indices 使它们在 x 索引的范围内并且至少为 1。删除 x_new[n] = x[0] 的错误插值

          >>> x_new_indices = x_new_indices.clip(1, len(x)-1).astype(int)
          
        • 计算每个x_new 值所在区域的斜率。

          >>> lo = x_new_indices - 1
          >>> hi = x_new_indices
          >>> x_lo = x[lo]
          >>> x_hi = x[hi]
          >>> y_lo = y[lo]
          >>> y_hi = y[hi]
          
        • 计算x_new中每个条目的实际值。

          >>> slope = (y_hi - y_lo) / (x_hi - x_lo)[:, None]
          >>> y_new = slope*(x_new - x_lo)[:, None] + y_lo
          

      【讨论】:

      • 很好的答案!让我确保我理解它。因此,当我将 5 输入为 x_new(我们将其称为 5)时,interp1d 将 5 排序到我的数组中,这样[5 5 10 10 10 20] 就变成了[five 5 5 10 10 10 20]。我的假设是,由于一些琐碎的原因,新的重复项总是放在现有相同条目的左侧。然后您提到的确保索引至少为 1 的过程将数组重新排列为[5 five 5 10 10 10 20]。因此斜率为NaN,因为x_lo = 5 和x_hi = 5。最后,y_new = NaN*0 = NaN
      猜你喜欢
      • 2016-01-05
      • 2022-07-22
      • 1970-01-01
      • 2018-04-13
      • 2020-09-03
      • 1970-01-01
      • 2022-09-23
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多