web-dev-qa-db-ja.com

Python / Scipy 2D補間(不均一なデータ)

これは私の以前の投稿へのフォローアップの質問です: Python/Scipy Interpolation(map_coordinates)

2Dの長方形の領域を補間したいとします。私の変数「z」には、以下に示すようなデータが含まれています。各列は一定の値ですが、以下のコメントに示すように、配列の各行は異なる値になる場合があります。

from scipy import interpolate
from numpy import array
import numpy as np
#                                               # 0.0000, 0.1750, 0.8170, 1.0000
z = array([[-2.2818,-2.2818,-0.9309,-0.9309],   # 0.0000, 0.0000, 0.0000, 0.0000
           [-2.2818,-2.2818,-0.9309,-0.9309],   # 0.2620, 0.2784, 0.3379, 0.3526
           [-1.4891,-1.4891,-0.5531,-0.5531],   # 0.6121, 0.6351, 0.7118, 0.7309
           [-1.4891,-1.4891,-0.5531,-0.5531]])  # 1.0000, 1.0000, 1.0000, 1.0000
# Rows, Columns = z.shape

cols = array([0.0000, 0.1750, 0.8170, 1.0000])
rows = array([0.0000, 0.2620, 0.6121, 1.0000])

sp = interpolate.RectBivariateSpline(rows, cols, z, kx=1, ky=1, s=0)

xi = np.array([0.00000, 0.26200, 0.27840, 0.33790, 0.35260, 0.61210, 0.63510,
               0.71180, 0.73090, 1.00000], dtype=np.float)
yi = np.array([0.000, 0.167, 0.815, 1.000], dtype=np.float)
print sp(xi, yi)

これを視覚化する別の方法として、私が知っている値の配列は次のようになります。

rows = array([0.0000, 0.2620, 0.2784, 0.3379, 0.3526,
                      0.6121, 0.6351, 0.7118, 0.7309, 1.0000])
#          # 0.0000, 0.1750, 0.8170, 1.0000
z = array([[-2.2818,-2.2818,-0.9309,-0.9309],   # 0.0000
           [-2.2818,      ?,      ?,      ?],   # 0.2620,
           [      ?,-2.2818,      ?,      ?],   # 0.2784
           [      ?,      ?,-0.9309,      ?],   # 0.3379
           [      ?      ,?,      ?,-0.9309],   # 0.3526
           [-1.4891,      ?,      ?,      ?],   # 0.6121
           [      ?,-1.4891,      ?,      ?],   # 0.6351
           [      ?,      ?,-0.5531,      ?],   # 0.7118
           [      ?,      ?,      ?,-0.5531],   # 0.7309
           [-1.4891,-1.4891,-0.5531,-0.5531]])  # 1.0000

「?」がわからない値、およびそれらは補間する必要があります。それらをNoneに置き換えてみましたが、すべての結果で「nan」が表示されます。

編集:

'griddata'または 'interp2'のいずれかを使用する必要があると思います。 griddataは私が期待する結果を生成するようですが、 'interp2'は生成しません。

from scipy import interpolate
from numpy import array
import numpy as np

z = array([[-2.2818,-2.2818,-0.9309,-0.9309],
           [-2.2818,-2.2818,-0.9309,-0.9309],
           [-1.4891,-1.4891,-0.5531,-0.5531],
           [-1.4891,-1.4891,-0.5531,-0.5531]])

rows = array([0.0000, 0.0000, 0.0000, 0.0000,
              0.2620, 0.2784, 0.3379, 0.3526,
              0.6121, 0.6351, 0.7118, 0.7309,
              1.0000, 1.0000, 1.0000, 1.0000])

cols = array([0.0000, 0.1750, 0.8180, 1.0000,
              0.0000, 0.1750, 0.8180, 1.0000,
              0.0000, 0.1750, 0.8180, 1.0000,
              0.0000, 0.1750, 0.8180, 1.0000])

xi = array([0.0000, 0.2620, 0.2784, 0.3379, 0.3526, 0.6121, 0.6351, 0.7118,
               0.7309, 1.0000], dtype=np.float)
yi = array([0.000, 0.175, 0.818, 1.000], dtype=np.float)

Gd = interpolate.griddata((rows, cols), z.ravel(),
                          (xi[None,:], yi[:,None]), method='linear')
I2 = interpolate.interp2d(rows, cols, z, kind='linear')

print Gd.reshape(4, 10).T
print '\n'
print I2(xi, yi).reshape(4, 10).T

import matplotlib.pyplot as plt
import numpy.ma as ma

plt.figure()
Gd = interpolate.griddata((rows.ravel(), cols.ravel()), z.ravel(),
                          (xi[None,:], yi[:,None]), method='linear')
CS = plt.contour(xi,yi,Gd,15,linewidths=0.5,colors='k')
CS = plt.contourf(xi,yi,Gd,15,cmap=plt.cm.jet)
plt.colorbar()
plt.scatter(rows,cols,marker='o',c='b',s=5)

plt.figure()
I2 = I2(xi, yi)
CS = plt.contour(xi,yi,I2,15,linewidths=0.5,colors='k')
CS = plt.contourf(xi,yi,I2,15,cmap=plt.cm.jet)
plt.colorbar()
plt.scatter(rows,cols,marker='o',c='b',s=5)
plt.show()
16
Scott B

あなたがそれを手に入れたように見えます。

上のコード例と前の( linked )の質問では、構造化データがあります。これは、RectBivariateSplineまたはinterp2dを使用して補間できます。これは、グリッド上に記述できるデータがあることを意味します(グリッド上のすべてのポイントには既知の値があります)。グリッドは必ずしもすべて同じdxとdyを持っている必要はありません。 (すべてのdxとdyが等しい場合、通常のグリッドがあります)

さて、あなたの現在の質問は、すべてのポイントがわかっていない場合にどうするかを尋ねています。これは、非構造化データとして知られています。あなたが持っているのは、フィールド内のポイントの選択だけです。すべての頂点が既知の値を持つ長方形を必ずしも作成できるとは限りません。このタイプのデータには、(お持ちのように)griddataまたはBivariateSplineのフレーバーを使用できます。

今、どちらを選択しますか?

構造化されたRectBivariateSplineに最も近いアナロジーは、unstructuredBivariateSplineclasses の1つです。 SmoothBivariateSplineまたはLSQBivariateSpline。スプラインを使用してデータを補間する場合は、これらを使用してください。これにより、関数は滑らかで微分可能になりますが、Z.max()またはZ.min()の外側でスイングするサーフェスを取得できます。

ky=1kx=1を設定していて、構造化データの線形補間であると私が確信しているものを取得しているので、個人的には、RectBivariateSplineスプラインスキームから interp2dstructuredグリッドに切り替えるだけです。補間スキーム。ドキュメントに 通常のグリッド 用であると記載されていることは知っていますが、__doc__自体の例は構造化のみです、定期的ではありません。

最終的に切り替えた場合に、メソッド間に大きな違いが見つかった場合は、興味があります。 SciPyへようこそ。

16
Paul