繁体   English   中英

在 numpy 数组中外推 NaN 值

[英]Extrapolate NaN values in a numpy array

我有两个值,并且知道它们在一个充满 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. 1.25 1.5 1.75 2. 2.25]

但是,我希望它是:

[0.25 0.5 0.75 1. 1.25 1.5 1.75 2. 2.25]

增量始终是一个常数。 当我阅读np.iterp文档时,我发现我可以指定输入参数leftright 如果我不指定left ,则x < xp[0]返回的值为fp[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])

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM