【问题标题】:2-d interpolation ignoring nan values忽略 nan 值的二维插值
【发布时间】:2016-03-28 06:31:42
【问题描述】:

你如何告诉 interp2d 忽略 nan 值?

我有一个表面 x 和 y 具有一些任意值 z。

x =   np.array([[9.19632, 9.62141, 10.0829, np.isnan, np.isnan],
        [9.21164, 9.64347, 10.1392, 10.5698,  np.isnan],
        [9.22175, 9.65439, 10.1423, 10.6301, 11.0323],
        [9.21632, 9.67060, 10.1474, 10.6230, 11.0818]])

y =  np.array([[11.5466,11.6485,11.7619, np.isnan, np.isnan],
        [12.4771, 12.5460, 12.5453, 12.7142, np.isnan],
        [13.5578, 13.5581, 13.5505, 13.5309, 13.6081],
        [14.5653, 14.5504, 14.5036, 14.5145, 14.5060]])

z = np.array([[0.466113, 0.0484404, -0.385355, np.isnan, np.isnan],
        [0.366125, -0.160165, -0.548668, -0.888301,np.isnan],
        [-0.0970777, -0.346734, -0.826576, -1.08412, -1.33129],
        [-0.259981, -0.586938, -1.03477, -1.32384, -1.61500]])

我已经能够使用蒙版数组生成上述颜色网格,但是当我尝试使用 2d 插值创建更精细的网格时失败了。以下是我到目前为止所拥有的,请注意,我将 nan 值设置为零以获得这一点,因此显然它会弄乱“正确”的插值。相反,我想忽略它们并将参数空间留空。

f = interp.interp2d(x,y,z, kind='linear')
xnew = np.arange(9,11.5, 0.01)
ynew = np.arange(9,15, 0.01)
znew = f(xnew, ynew)


levels = np.linspace(zmin, zmax, 15)
plt.ylabel('Y', size=15)
plt.xlabel('X', size=15)
cmap = plt.cm.jet_r
cmap.set_bad('white',0.1) # set nan to white
cs = plt.contourf(xnew, ynew, znew, levels=levels, cmap=cmap)
cbar = plt.colorbar(cs)
cbar.set_label('Z', rotation=90, fontsize=15) # gas fraction
plt.show()

我想简单地创建一个平滑的颜色图,其中由 x 和 y 限制的区域根据 z 着色。

【问题讨论】:

    标签: python matplotlib scipy interpolation


    【解决方案1】:

    我不知道为什么 interp2d 存在不规则间隔数据的问题,我建议使用 griddata,您可以将输入数据扁平化为带有 ravel 的向量,然后消除 NaN,并将其用作 griddata 的输入,你会得到这样的东西

    代码与你拥有的没有太大区别

    import numpy as np
    import matplotlib.pyplot as plt
    from scipy.interpolate import griddata
    
    x =   np.array([[9.19632, 9.62141, 10.0829,np.isnan,np.isnan],
        [9.21164, 9.64347, 10.1392, 10.5698,np.isnan],
        [9.22175, 9.65439, 10.1423, 10.6301, 11.0323],
        [9.21632, 9.67060, 10.1474, 10.6230, 11.0818]])
    
    y =  np.array([[11.5466,11.6485,11.7619,np.isnan,np.isnan],
        [12.4771, 12.5460, 12.5453, 12.7142,np.isnan],
        [13.5578, 13.5581, 13.5505, 13.5309, 13.6081],
        [14.5653, 14.5504, 14.5036, 14.5145, 14.5060]])
    
    z = np.array([[0.466113, 0.0484404, -0.385355,np.isnan,np.isnan],
        [0.366125, -0.160165, -0.548668, -0.888301,np.isnan],
        [-0.0970777, -0.346734, -0.826576, -1.08412, -1.33129],
        [-0.259981, -0.586938, -1.03477, -1.32384, -1.61500]])
    
    x=x.ravel()              #Flat input into 1d vector
    x=list(x[x!=np.isnan])   #eliminate any NaN
    y=y.ravel()
    y=list(y[y!=np.isnan])
    z=z.ravel()
    z=list(z[z!=np.isnan])
    
    
    xnew = np.arange(9,11.5, 0.01)
    ynew = np.arange(9,15, 0.01)
    znew = griddata((x, y), z, (xnew[None,:], ynew[:,None]), method='linear')
    
    
    
    levels = np.linspace(min(z), max(z), 15)
    plt.ylabel('Y', size=15)
    plt.xlabel('X', size=15)
    cmap = plt.cm.jet_r
    cs = plt.contourf(xnew, ynew, znew, levels=levels, cmap=cmap)
    cbar = plt.colorbar(cs)
    cbar.set_label('Z', rotation=90, fontsize=15) # gas fraction
    plt.show()
    

    如果你必须推断数据(查看我下面的评论),你可以使用SmoothBivariateSpline 并使用样条线的顺序,我不推荐它,我会告诉你原因。

    代码更接近你原来的。

    from scipy.interpolate import SmoothBivariateSpline
    
    x=x.ravel()
    x=(x[x!=np.isnan])
    y=y.ravel()
    y=(y[y!=np.isnan])
    z=z.ravel()
    z=(z[z!=np.isnan])
    
    xnew = np.arange(9,11.5, 0.01)
    ynew = np.arange(10.5,15, 0.01)
    
    f = SmoothBivariateSpline(x,y,z,kx=1,ky=1)
    
    znew=np.transpose(f(xnew, ynew))
    

    如果 kx=1 和 ky=1 f = SmoothBivariateSpline(x,y,z,kx=1,ky=1) 你会得到

    如果 kx=2 和 ky=2,你会得到:

    如果 kx=3 和 ky=3,你会得到:

    我更改了 3 张图片的级别,以便于查看。但是请检查规模,在您的采样区域之外,值可能会很快变得疯狂,所以如果您必须推断,请谨慎行事

    【讨论】:

    • 谢谢 - 比 interp2d 好得多。是否可以推断输入网格之外的 xnew,ynew 坐标的 z 值?您可以使用 'fill_value' 关键字将它们设置为常量,或者使用 'nearest' 方法创建一个相当难看的近似值。但是,理想情况下,我希望在每个 xnew,ynew 处进行平滑外推,以便填充参数空间。
    • 2d 中的外推是一个非常重要的问题,取决于你在做什么,最好有 NaN,这样你就知道它在采样区域之外,但如果你必须,也许线性外推是一个安全的选择,但你可以很快地越界。我将编辑答案以包含一些用SmoothBivariateSpline进行推断的图像
    • 我同意,你必须警惕 2d 外推,这是一个很好的例子。您能否编辑以显示您如何参加SmoothBivariateSpline 课程。感谢您的帮助。
    • 当然,我是不同的导入,我会添加它,代码更接近你原来的代码
    • 啊转置(!)。现在说得通了:)
    猜你喜欢
    • 1970-01-01
    • 2019-09-24
    • 1970-01-01
    • 1970-01-01
    • 2020-07-17
    • 2016-06-03
    • 2012-09-09
    • 2016-10-11
    • 1970-01-01
    相关资源
    最近更新 更多