首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >用LinearNDInterpolator外推

用LinearNDInterpolator外推
EN

Stack Overflow用户
提问于 2013-12-11 10:34:36
回答 3查看 3.3K关注 0票数 2

我有一个三维数据集,我想要插值和外推线性。利用scipy.interpolate.LinearNDInterpolator可以方便地进行插补。该模块只能为参数范围以外的值填充一个常量/nan,但我不明白它为什么不提供打开外推的选项。

查看代码,我看到模块是用cython编写的。由于没有使用cython的经验,很难使用代码来实现外推。我可以用纯python代码编写它,但也许这里的其他人有更好的想法?我的特殊情况涉及一个常量的xy网格,但是z值一直在变化(-100,000),因此插值必须是快速的,因为每次z值变化时,插值都会运行。

为了给出一个基本的例子,如所请求的,让我们说我有一个网格,如

代码语言:javascript
运行
复制
xyPairs = [[-1.0, 0.0], [-1.0, 4.0],
           [-0.5, 0.0], [-0.5, 4.0],
           [-0.3, 0.0], [-0.3, 4.0],
           [+0.0, 0.0], [+0.0, 4.0],
           [+0.2, 0.0], [+0.2, 4.0]]

假设我想在x = -1.5, -0.8, +0.5y = -0.2, +0.2, +0.5上计算值。目前,我正在对每个y值沿x轴进行一维插值/外推,然后对每个x值沿y轴进行插值/外推。外推是由ryggyr's answer中的第二个函数完成的。

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2014-01-31 15:04:15

我提出了一个方法,代码很糟糕,但我希望它能帮助你。这样做的想法是,如果预先知道必须外推的界限,则可以在数组的边缘添加具有线性外推值的额外列/行,然后在新数组上进行内插。下面是一个例子,一些数据将被外推,直到x=+-50和y=+-40为止:

代码语言:javascript
运行
复制
import numpy as np
x,y=np.meshgrid(np.linspace(0,6,7),np.linspace(0,8,9)) # create x,y grid
z=x**2*y # and z values
# create larger versions with two more columns/rows
xlarge=np.zeros((x.shape[0]+2,x.shape[1]+2))
ylarge=np.zeros((x.shape[0]+2,x.shape[1]+2))
zlarge=np.zeros((x.shape[0]+2,x.shape[1]+2))
xlarge[1:-1,1:-1]=x # copy data on centre
ylarge[1:-1,1:-1]=y
zlarge[1:-1,1:-1]=z
# fill extra columns/rows
xmin,xmax=-50,50
ymin,ymax=-40,40
xlarge[:,0]=xmin;xlarge[:,-1]=xmax # fill first/last column
xlarge[0,:]=xlarge[1,:];xlarge[-1,:]=xlarge[-2,:] # copy first/last row
ylarge[0,:]=ymin;ylarge[-1,:]=ymax
ylarge[:,0]=ylarge[:,1];ylarge[:,-1]=ylarge[:,-2]
# for speed gain: store factor of first/last column/row
first_column_factor=(xlarge[:,0]-xlarge[:,1])/(xlarge[:,1]-xlarge[:,2]) 
last_column_factor=(xlarge[:,-1]-xlarge[:,-2])/(xlarge[:,-2]-xlarge[:,-3])
first_row_factor=(ylarge[0,:]-ylarge[1,:])/(ylarge[1,:]-ylarge[2,:])
last_row_factor=(ylarge[-1,:]-ylarge[-2,:])/(ylarge[-2,:]-ylarge[-3,:])
# extrapolate z; this operation only needs to be repeated when zlarge[1:-1,1:-1] is updated
zlarge[:,0]=zlarge[:,1]+first_column_factor*(zlarge[:,1]-zlarge[:,2]) # extrapolate first column
zlarge[:,-1]=zlarge[:,-2]+last_column_factor*(zlarge[:,-2]-zlarge[:,-3]) # extrapolate last column
zlarge[0,:]=zlarge[1,:]+first_row_factor*(zlarge[1,:]-zlarge[2,:]) # extrapolate first row
zlarge[-1,:]=zlarge[-2,:]+last_row_factor*(zlarge[-2,:]-zlarge[-3,:]) #extrapolate last row

然后,您可以插值(xlarge,ylarge,zlarge)。因为所有的操作都是numpy片操作,所以我希望它对您来说足够快。当z数据被更新时,在zlarge[1:-1,1:-1]中复制它们并重新执行最后4行。

票数 4
EN

Stack Overflow用户

发布于 2018-02-12 23:54:17

使用最近插值和线性插值的组合。如果LinearNDInterpolator不能插值,则返回np.nan,否则返回数组大小(1) NearestNDInterpolator返回浮点数

代码语言:javascript
运行
复制
import scipy.interpolate
import numpy
class LinearNDInterpolatorExt(object):
  def __init__(self, points,values):
    self.funcinterp=scipy.interpolate.LinearNDInterpolator(points,values)
    self.funcnearest=scipy.interpolate.NearestNDInterpolator(points,values)
  def __call__(self,*args):
    t=self.funcinterp(*args)
    if not numpy.isnan(t):
      return t.item(0)
    else:
      return self.funcnearest(*args)
票数 4
EN

Stack Overflow用户

发布于 2020-12-07 05:45:15

我稍微修改了@Keith的答案,这对我很有用(注意到它并不是线性地推断--它只使用最近的邻居):

代码语言:javascript
运行
复制
import numpy as np
from scipy.interpolate import LinearNDInterpolator as linterp
from scipy.interpolate import NearestNDInterpolator as nearest

class LinearNDInterpolatorExt(object):
    def __init__(self, points, values):
        self.funcinterp = linterp(points, values)
        self.funcnearest = nearest(points, values)
    
    def __call__(self, *args):
        z = self.funcinterp(*args)
        chk = np.isnan(z)
        if chk.any():
            return np.where(chk, self.funcnearest(*args), z)
        else:
            return z
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/20516762

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档