Unable to interprete MATLAB interp2d in Python scipy.interp

匿名 (未验证) 提交于 2019-12-03 01:45:01

问题:

The following code is just to understand the context. My question doesn't require much understanding of this. It need a simple translation of one line of MATLAB code in to 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 

So after this step the code should do interpolation and in MATLAB it's like this:

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

My proj, uu and vv are (1024,1024) and pu, pv are (360,360). I need to convert the above line to Python. I tried using scipy.interpolate but it gives the following errors on trying these :

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

TypeError: unhashable type: 'numpy.ndarray'

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

OverflowError: Too many data points to interpolate

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

ValueError: x and y must have equal lengths for non rectangular grid

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

ValueError: Invalid length for input z for non rectangular grid

I have read all the scipy.interpolate documentations and none seemed to help. Could anyone figure out what's wrong?

回答1:

The problem on a wide scale is that you're looking at the documentation but you're not trying to understand it. If you're using a specific function interp2d in the module scipy.interpolate, then look at the function's documentation, as @pv also suggested in a comment. The fact that you're throwing the arguments all around the place clearly demonstrates that you're trying to use a function based on guesswork. It won't work: a function was implemented with a given syntax, and it will only work like that.

So look at the function's signature:

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

The meaning of the parameters is explained afterwards. You can clearly see that there are 3 mandatory parameters: x, y, z. No other array-valued inputs are allowed This is because interp2d only constructs an interpolating function, which you should then use to compute the interpolated values on a mesh (unlike MATLAB, where interp2d gives you the interpolated values directly). So you can call

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

to get an interpolating function. You can then substitute at the given values, but note that the function myfun will expect 1d input, and it will construct a mesh internally. So assuming that your output mesh is constructed as

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

(which is probably not the case, but I'll get back to this later), you need

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

to obtain the output you need.

However, there are some important points you should note.

  1. In MATLAB you have interp2d(uu,vv,proj',...), but make sure that for scipy the elements of uu, vv, and proj are in the same order. To be on the safe side: in case of an asymmetric mesh size, the shape of uu, vv and proj should all be the same.
  2. In MATLAB you're using 'linear' interpolation, while in python you're using 'cubic'. I'm not sure this is really what you want, if you're porting your code to a new language.
  3. It seems to me that your output mesh is not defined by a rectangular grid as if from meshgrid, which suggests that interp2d might not be suitable for your case. Anyway, I've had some odd experiences with interp2d, and I wouldn't trust it. So if it's not suitable for your expected output, I'd strongly suggest using scipy.interpolate.griddata instead. This function gives you interpolated points directly: I suggest that you try to figure out its use based on the manual:) My linked answer can also help. You can set the kind of interpolation in the same way, but your output can be any set of scattered points if you like.


标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!