如果我想插入以下数据:
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)
interp2d
这有效:
f = interp2d(x1, y1, z, kind='cubic')
但是如果我使用RectBivariateSpline
使用相同的x1,y1参数:
f = RectBivariateSpline(x1, y1, z)
我收到此错误:
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
我必须像这样切换x,y的大小才能让它工作:
x2 = np.linspace(0,5,20)
y2 = np.linspace(0,20,10)
f = RectBivariateSpline(x2, y2, z)
是否存在这种行为的原因 - 或者我不理解的事情?
答案 0 :(得分:1)
嗯,原因是,正如您所指出的,两个函数的参数不同。是的,正如我所知,这使得很难为另一个换掉一个。
为什么呢?一般来说,明确的设计决定是要破坏与新的面向对象样条函数的向后兼容性,或者至少不要担心它。当然,对于较大的网格尺寸,可以节省大量空间,而不必将x和y作为2D对象传递。坦率地说,我在我的代码中发现,一旦克服了这个初始障碍,我就会更乐意使用样条对象。例如,使用UnivariateSpline对象,获取衍生物很容易,就像积分一样。
看起来,未来,SciPy人员将专注于新物体,所以你可能会考虑现在就转移到它们身上。它们具有相同的基本功能,并且有其他方法可以提供很好的好处。
编辑 - 澄清两者之间的“破裂”。从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’)
遗憾的是,这可能会产生误导,因为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
现在它们有不同的形状:shape(z)
是(11,21),shape(zz)
是(21,11)。事实上,它们是彼此的转置,z
== zz.T
。一旦你意识到这一点,一切都会变得更加清晰 - 从interp2d
到RectBivariateSpline
交换预期的轴。选择样条曲线的一个实例(我选择了新的样条曲线),并选择了一组特定的轴来保持清晰。要将它们混合在一起,一个简单的转置也可以正常工作,但是从现在起一个月或更长时间内回溯代码时可能会很头疼。