【问题标题】:Unable to interprete MATLAB interp2d in Python scipy.interp无法在 Python scipy.interp 中解释 MATLAB interp2d
【发布时间】:2016-06-27 14:37:44
【问题描述】:

下面的代码只是为了理解上下文。我的问题不需要对此有太多了解。它需要将一行 MATLAB 代码简单地翻译成 Python。

us = np.linspace(-(1023)/2,(1023)/2,1024)
vs = np.linspace(-(1023)/2,(1023)/2,1024)
uu,vv = np.meshgrid(-us,vs)
pu = ((((rx*SDD)/(ry+SOD))+us[0])/(-du))+1

xs = np.linspace(-(360-1)/2,(nx-1)/2,360)
ys = np.linspace(-(360-1)/2,(ny-1)/2,360)
zs = np.linspace(-(360-1)/2,(ny-1)/2,360)

xx,yy = np.meshgrid(xs,ys)

angle_rad = np.linspace(0,359,360)
angle_rad = angle_rad*np.pi/180

for i in range(0,360) :
    vol = np.zeros((360,360,360))
    rx = xx*np.cos(angle_rad[i]-np.pi/2) + yy*np.sin(angle_rad[i]-np.pi/2)
    ry = -xx*np.sin(angle_rad[i]-np.pi/2) + yy*np.cos(angle_rad[i]-np.pi/2)
    pu = ((((rx*370)/(ry+9))+us[0])/(-51.2/1024))+1

    for iz in range(0,360) :
        pv = ((((zs[iz]*370)/(ry+9))-vs[0])/(51.2/1024)) +1

所以在这一步之后,代码应该进行插值,在 MATLAB 中是这样的:

vol(:,:,iz) = interp2(uu,vv ,proj',pu,pv,'linear'); This is in MATLAB

我的 proj, uu 和 vv 是 (1024,1024) 而 pu, pv 是 (360,360)。我需要将上面的行转换为 Python。我尝试使用 scipy.interpolate 但在尝试这些时会出现以下错误:

vol[:,:,iz] = Ratio*(interp2d(uu,vv,proj,pu,pv,'cubic'))

TypeError: unhashable type: 'numpy.ndarray'

vol[:,:,iz] = Ratio*(interp2d(uu,vv,proj,'cubic'))

OverflowError:要插入的数据点太多

vol[:,:,iz] = Ratio*(interp2d(proj,pu,pv,'cubic'))

ValueError: 对于非矩形网格,x 和 y 的长度必须相等

vol[:,:,iz] = Ratio*(interp2d(pu,pv,proj,'cubic'))

ValueError:非矩形网格的输入 z 长度无效

我已阅读所有 scipy.interpolate 文档,但似乎没有任何帮助。有人能弄清楚是什么问题吗?

【问题讨论】:

标签: python python-2.7 python-3.x scipy


【解决方案1】:

大范围的问题是您正在查看文档,但您并没有尝试理解它。如果您在模块scipy.interpolate 中使用特定函数interp2d,则look at the function's documentation,如@pv also suggested in a comment。您到处乱扔参数这一事实清楚地表明您正在尝试使用基于猜测的函数。它不起作用:一个函数是用给定的语法实现的,它只能这样工作。

那么看一下函数的签名:

class scipy.interpolate.interp2d(x, y, z, kind='linear', copy=True, bounds_error=False, fill_value=nan)

后面会解释参数的含义。可以清楚的看到有3个强制参数:xyz。不允许其他数组值输入 这是因为 interp2d 仅构造一个插值 函数,然后您应该使用它来计算网格上的插值(与 MATLAB 不同,interp2d 为您提供直接插值)。所以你可以打电话

myfun = interp2(uu,vv,proj,'linear')

得到一个插值函数。然后您可以替换给定值,但请注意函数myfun 将需要一维输入,并且它将在内部构造一个网格。因此,假设您的输出网格构造为

puu,puv = np.meshgrid(puu_vec,puv_vec)

(可能不是这种情况,但我稍后再谈),你需要

vol[:,:,iz] = Ratio*myfun(puu_vec,puv_vec)

获取你需要的输出。

但是,您应该注意一些重要的点。

  1. 在 MATLAB 中,您有 interp2d(uu,vv,proj',...),但请确保对于 scipyuuvvproj 的元素顺序相同。为了安全起见:如果网格尺寸不对称,uuvvproj 的形状应该都相同。
  2. 在 MATLAB 中,您使用的是 'linear' 插值,而在 python 中,您使用的是 'cubic'。如果您要将代码移植到新语言,我不确定这是否真的是您想要的。
  3. 在我看来,您的输出网格不是由矩形网格定义的,就像来自meshgrid,这表明interp2d might not be suitable for your case。无论如何,I've had some odd experiences with interp2d,我不会相信它。因此,如果它不适合您的预期输出,我强烈建议您改用scipy.interpolate.griddata。此功能直接为您提供插值点:我建议您尝试根据手册找出它的用途:) 我的链接答案也可以提供帮助。您可以以相同的方式设置插值类型,但如果您愿意,您的输出可以是任何散点集。

【讨论】:

  • 我试过这个。 f = interp2d(uu,vv,proj,'cubic') vol[:,:,iz] = Ratio*f(pu,pv) 但它说 OverflowError: Too many data points to interpolate。我的 pu 和 pv 是(360,360),如果输入应该是一维的,我尝试 pu=pu.reshape(pu.size) 和 pv 相同以使其成为一维。但它仍然给出相同的溢出错误。
  • @PrakritiKumari 仔细阅读了我的示例代码。问题不是 shape,而是点本身的结构。如果您的输入点是[0,0][0,1][1,0][1,1],那么您的pupv 类似于[[0,0],[1,1]][[0,1],[0,1]](或相反)。如果要对这些 2x2 点进行插值,则只需将两个 2 元素向量提供给插值器:f([0,1],[0,1])。因此,相同的向量进入f(),可用于生成带有meshgrid 的网格。
  • 这就是为什么我说如果你的点不在网格上,你就不能使用interp2d。或者至少使用griddata 会更好。你现在明白了吗?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2014-12-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-12-11
  • 1970-01-01
相关资源
最近更新 更多