在x、y参数的差值上,用scipy插值法和interp2d进行比较

时间:2021-07-31 18:15:29

If I want to interpolate the data below:

如果我想插入以下数据:

from scipy.interpolate import RectBivariateSpline, interp2d
import numpy as np

x1 = np.linspace(0,5,10)
y1 = np.linspace(0,20,20)
xx, yy = np.meshgrid(x1, y1)
z = np.sin(xx**2+yy**2) 

with interp2d this works:

与interp2d如此:

f = interp2d(x1, y1, z, kind='cubic')

however if I use RectBivariateSpline with the same x1, y1 parameters:

但是,如果我使用具有相同x1, y1参数的RectBivariateSpline:

f = RectBivariateSpline(x1, y1, z)

I get this error:

我得到这个错误:

   TypeError                                 Traceback (most recent call last)
<ipython-input-9-3da046e1ebe0> in <module>()
----> 1 f = RectBivariateSpline(x, y, z)

C:\...\Local\Continuum\Anaconda\lib\site-packages\scipy\interpolate\fitpack2.pyc in __init__(self, x, y, z, bbox, kx, ky, s)
    958             raise TypeError('y must be strictly ascending')
    959         if not x.size == z.shape[0]:
--> 960             raise TypeError('x dimension of z must have same number of '
    961                             'elements as x')
    962         if not y.size == z.shape[1]:

TypeError: x dimension of z must have same number of elements as x

I'd have to switch the sizes of x, y like this to have it work:

我得把x和y的尺寸像这样调换一下才能让它工作:

x2 = np.linspace(0,5,20)
y2 = np.linspace(0,20,10)
f = RectBivariateSpline(x2, y2, z)

Is there a reason for this behavior - or something I am not understanding?

这种行为是有原因的还是我不理解的?

1 个解决方案

#1


1  

Well, the reason is that the parameters to the two functions are, as you have noted, different. Yes, this makes it really hard to just switch out one for the other, as I well know.

原因是这两个函数的参数是不同的。是的,我知道,这让我很难把其中一个换成另一个。

Why? In general it was a clear design decision to break backward compatibility with the new object-oriented spline functions, or at least not worry about it. Certainly, for large grid sizes there is significant space savings with not having to pass x and y as 2D objects. Frankly, I have found in my code that once this initial barrier is overcome, I'm much happier using the spline objects. For example, with the UnivariateSpline object, getting the derivative(s) is easy, as is the integral.

为什么?一般来说,打破与新的面向对象样条函数的向后兼容性是一个明确的设计决策,或者至少不用担心这个问题。当然,对于较大的网格大小,不需要将x和y作为2D对象传递,可以节省大量空间。坦率地说,我在代码中发现,一旦克服了最初的障碍,使用样条对象就会更快乐。例如,对于UnivariateSpline对象,得到导数(s)很简单,就像积分一样。

It would appear that, going forward, the SciPy folks will focus on the new objects, so you might contemplate just moving to them now. They are the same base functionality, and have additional methods that provide nice benefits.

看起来,未来SciPy人员将会关注新的对象,所以您可能会考虑现在就转移到它们上面。它们是相同的基本功能,并具有提供良好好处的附加方法。

EDIT - clarify what 'broke' between the two.

编辑-澄清两者之间的“断裂”。

From the SciPy manual on interp2d you get the code snippet:

从interp2d的SciPy手册中,您可以得到代码片段:

from scipy import interpolate
x = np.arange(-5.01, 5.01, 0.25)
y = np.arange(-5.01, 5.01, 0.25)
xx, yy = np.meshgrid(x, y)
z = np.sin(xx**2+yy**2)
f = interpolate.interp2d(x, y, z, kind=’cubic’)

This can be, unfortunately, potentially misleading since both x and y are the same length, so z will be a square matrix. So, lets play with this a bit:

不幸的是,这可能有潜在的误导性,因为x和y的长度相同,所以z是一个方阵。让我们来玩一下这个:

x = np.linspace(0,5,11) 
y = np.linspace(0,20,21) # note different lengths
z = x[None,:].T + y*y # need broadcasting
xx,yy = np.meshgrid(x,y) # this is from the interp2d example to compare
zz = xx + yy*yy

These now have different shapes: shape(z) is (11,21) and shape(zz) is (21,11). In fact, they are the transpose of each other, z == zz.T. Once you realize this, it all becomes clearer - going from interp2d to RectBivariateSpline swapped the expected axes. Pick one instantiation of the splines (I've opted for the newer ones), and you have picked a particular set of axes to keep clear in your head. To mix them together, a simple transpose will work as well, but can get to be a headache when you go back through your code a month or more from now.

它们现在有不同的形状:shape(z) is(11,21)和shape(zz) is(21,11)。实际上,它们是彼此的转置,z = z。t。一旦你意识到这一点,一切就变得更清晰了——从interp2d到RectBivariateSpline交换了期望的轴。选择一个样条的实例化(我选择了较新的),然后您选择了一组特定的轴,以便在头脑中保持清晰。要将它们混合在一起,一个简单的转置也可以工作,但是当您在一个月或更长的时间内回顾您的代码时,可能会感到头痛。

#1


1  

Well, the reason is that the parameters to the two functions are, as you have noted, different. Yes, this makes it really hard to just switch out one for the other, as I well know.

原因是这两个函数的参数是不同的。是的,我知道,这让我很难把其中一个换成另一个。

Why? In general it was a clear design decision to break backward compatibility with the new object-oriented spline functions, or at least not worry about it. Certainly, for large grid sizes there is significant space savings with not having to pass x and y as 2D objects. Frankly, I have found in my code that once this initial barrier is overcome, I'm much happier using the spline objects. For example, with the UnivariateSpline object, getting the derivative(s) is easy, as is the integral.

为什么?一般来说,打破与新的面向对象样条函数的向后兼容性是一个明确的设计决策,或者至少不用担心这个问题。当然,对于较大的网格大小,不需要将x和y作为2D对象传递,可以节省大量空间。坦率地说,我在代码中发现,一旦克服了最初的障碍,使用样条对象就会更快乐。例如,对于UnivariateSpline对象,得到导数(s)很简单,就像积分一样。

It would appear that, going forward, the SciPy folks will focus on the new objects, so you might contemplate just moving to them now. They are the same base functionality, and have additional methods that provide nice benefits.

看起来,未来SciPy人员将会关注新的对象,所以您可能会考虑现在就转移到它们上面。它们是相同的基本功能,并具有提供良好好处的附加方法。

EDIT - clarify what 'broke' between the two.

编辑-澄清两者之间的“断裂”。

From the SciPy manual on interp2d you get the code snippet:

从interp2d的SciPy手册中,您可以得到代码片段:

from scipy import interpolate
x = np.arange(-5.01, 5.01, 0.25)
y = np.arange(-5.01, 5.01, 0.25)
xx, yy = np.meshgrid(x, y)
z = np.sin(xx**2+yy**2)
f = interpolate.interp2d(x, y, z, kind=’cubic’)

This can be, unfortunately, potentially misleading since both x and y are the same length, so z will be a square matrix. So, lets play with this a bit:

不幸的是,这可能有潜在的误导性,因为x和y的长度相同,所以z是一个方阵。让我们来玩一下这个:

x = np.linspace(0,5,11) 
y = np.linspace(0,20,21) # note different lengths
z = x[None,:].T + y*y # need broadcasting
xx,yy = np.meshgrid(x,y) # this is from the interp2d example to compare
zz = xx + yy*yy

These now have different shapes: shape(z) is (11,21) and shape(zz) is (21,11). In fact, they are the transpose of each other, z == zz.T. Once you realize this, it all becomes clearer - going from interp2d to RectBivariateSpline swapped the expected axes. Pick one instantiation of the splines (I've opted for the newer ones), and you have picked a particular set of axes to keep clear in your head. To mix them together, a simple transpose will work as well, but can get to be a headache when you go back through your code a month or more from now.

它们现在有不同的形状:shape(z) is(11,21)和shape(zz) is(21,11)。实际上,它们是彼此的转置,z = z。t。一旦你意识到这一点,一切就变得更清晰了——从interp2d到RectBivariateSpline交换了期望的轴。选择一个样条的实例化(我选择了较新的),然后您选择了一组特定的轴,以便在头脑中保持清晰。要将它们混合在一起,一个简单的转置也可以工作,但是当您在一个月或更长的时间内回顾您的代码时,可能会感到头痛。