4

我在网格上有一个带有矩形数据的 numpy 数组,并希望在其上拟合 2-D 样条以重现大规模变化,同时消除所有/大部分噪声。数据也有一些区域用 NaN 值标记为无效。

我尝试使用 scipy.interpolate.RectBivariateSpline 函数,但差距搞砸了结果。所以我尝试使用同一个包中的 LSQBivariateSpline 函数,希望当我将所有 NaN 像素的权重设置为 0 时,它会简单地忽略它们。但是,那时我遇到了以下我不知道如何避免的错误:

我的代码是:

# some preparation, loading data and stuff
# all my data is stored in 'data'

# Create the knots (10 knots in each direction, making 100 total
xcoord = numpy.linspace(5, data.shape[0]-5, 10)
ycoord = numpy.linspace(5, data.shape[1]-5, 10)

# Create all weights, and set them to 0 when the data is NaN
weights = numpy.ones(data.shape)
weights[numpy.isnan(data)] = 1e-15  # weights must be >0

# LSQBivariateSpline needs x and y coordinates as 1-D arrays
x, y = numpy.indices(data.shape)
spline_fit = scipy.interpolate.LSQBivariateSpline(x.ravel(), y.ravel(), data.ravel(), 
                                               xcoord, ycoord, 
                                               w=weights.ravel(),
                                               bbox=[None, None, None, None], 
                                               kx=2, ky=2)

代码的输出是以下错误消息:

The coefficients of the spline returned have been computed as the
minimal norm least-squares solution of a (numerically) rank deficient
system (deficiency=25). If deficiency is large, the results may be
inaccurate. Deficiency may strongly depend on the value of eps.
done!
Traceback (most recent call last):
  File "./fitpg.py", line 513, in <module>
    fit_pupilghost(prebinned, (center_y, center_x), (r_inner, r_outer), dr)
  File "./fitpg.py", line 298, in fit_pupilghost
    fitout = pupil2d(radius[:,y], angle[:,y])
  File "/usr/local/lib64/python2.7/site-packages/scipy/interpolate/fitpack2.py", line 545, in __call__
    raise ValueError("Error code returned by bispev: %s" % ier)
ValueError: Error code returned by bispev: 10

我输入的输入矩阵(“数据”)大约为 1000 x 1000 像素,这足以将样条线约束在 100 节。将每个方向上的节数增加到 100 个,代码运行速度会变慢,但除了不足数之外,没有任何变化。我还尝试使用 1-e30 到 0.9 之间的值增加和减少 eps 值(默认为 1e-16

我也尝试用谷歌搜索错误代码,但找不到好的结果,所以这也无济于事。

知道这里可能有什么问题吗?还是有解决此问题的解决方法/更好的方法?

任何帮助将不胜感激。

谢谢

4

1 回答 1

6

样条拟合代码不以任何特殊方式处理 NaN。由于任何与 NaN 接触的数字也会变成 NaN,这意味着它们的存在会毒化整个计算,因此您不会得到任何结果。

您可以做的是用一些(任意)有限值替换 NaN 值,例如,除了设置零权重

weights = numpy.ones(data.shape)
mask = numpy.isnan(data)
weights[mask] = 0
data[mask] = 0   # arbitrary

由于重量很小,因此选择的值无关紧要。1e-15如果由于某种原因不喜欢零权重,您也可以尝试将相应的权重设置为较小的值,例如 your 。

于 2013-02-07T10:22:50.803 回答