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 に増やすと、コードの実行速度がかなり遅くなりますが、不足数を除いて何も変わりません。また、eps 値を 1-e30 から 0.9 の間の値で増減しようとしました (デフォルトは 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何らかの理由でゼロの重みが気に入らない場合は、対応する重みを のような小さな値に設定することもできます。

于 2013-02-07T10:22:50.803 に答える