推断在numpy NaN值数组



我有两个值,并且知道它们在一个充满nan的数组中的索引。我想插入/推断所有的南

import numpy as np
y = np.array([np.nan, np.nan, 0.75, np.nan, np.nan, np.nan, np.nan, np.nan, 2.25])
在这个答案的帮助下,我写了以下内容:
nans, x = np.isnan(y), lambda z: z.nonzero()[0]
y[nans] = np.interp(x(nans), x(~nans), y[~nans])

我的输出看起来如下:

[0.75 0.75 0.75]1.25 1.5 1.75 2。2.25)

但是,我希望它是:

[0.25 0.5 0.75]1.25 1.5 1.75 2。2.25)

增量总是一个常数。当我阅读np.iterp的文档时,我看到我可以指定输入参数leftright。如果不指定left,则xfp [0]

我如何指定leftright以获得所需的输出?

np.interp似乎没有外推,但scipy.interpolate.interp1d有。

给出的参数有点不同,您可以根据您的特殊情况将其设置为函数:

import numpy as np
from scipy.interpolate import interp1d

def interp_nans(y, x=None):
if x is None:
x = np.arange(len(y))
nans = np.isnan(y)
interpolator = interp1d(
x[~nans],
y[~nans],
kind="linear",
fill_value="extrapolate",
assume_sorted=True,
)
return interpolator(x)

检查是否有效:

y = np.array([np.nan, np.nan, 0.75, np.nan, np.nan, np.nan, np.nan, np.nan, 2.25])
expected = np.array([0.25, 0.5, 0.75, 1.0, 1.25, 1.5, 1.75, 2.0, 2.25])
result = interp_nans(y)
assert np.array_equal(result, expected)

您不能指定leftright来实现与interp的外推,它们只是常量值。

如果您喜欢纯numpy解决方案,您可以根据插值数组的前/后两个值进行线性外推:

def extrap(x, xp, fp):
m = (fp[1] - fp[0]) / (xp[1] - xp[0])
n = fp[0] - m * xp[0]
result = m * x[x < xp[0]] + n
m = (fp[-1] - fp[-2]) / (xp[-1] - xp[-2])
n = fp[-1] - m * xp[-1]
return np.concatenate([result, m * x[x > xp[-1]] + n])

(您可能希望添加验证len(xp) > 1len(xp) == len(yp))

的例子:

y = np.array([np.nan, np.nan, 0.75, np.nan, np.nan, np.nan, np.nan, np.nan, 2.25, np.nan])
nans, x = np.isnan(y), lambda z: z.nonzero()[0]
y[nans] = np.interp(x(nans), x(~nans), y[~nans], np.nan, np.nan)
nans, x = np.isnan(y), lambda z: z.nonzero()[0]
y[nans] = extrap(x(nans), x(~nans), y[~nans])
结果

array([0.25, 0.5 , 0.75, 1.  , 1.25, 1.5 , 1.75, 2.  , 2.25])

最新更新