私はプログラミングが新しく、線形補間関数を書こうと思っていました。線形補間 - Python
は、以下のように、私はデータを与えてい言う: X = [1、2.5、3.4、5.8、6] Y = [2、4、5.8、4.3、4]
I関数を設計しますPythonを使用して1と2.5,2.5〜3.4などの線形補間を行います。
私は http://docs.python.org/tutorial/に目を通してみましたが、それでも私の頭の中で頭を上げることはできません。
私はプログラミングが新しく、線形補間関数を書こうと思っていました。線形補間 - Python
は、以下のように、私はデータを与えてい言う: X = [1、2.5、3.4、5.8、6] Y = [2、4、5.8、4.3、4]
I関数を設計しますPythonを使用して1と2.5,2.5〜3.4などの線形補間を行います。
私は http://docs.python.org/tutorial/に目を通してみましたが、それでも私の頭の中で頭を上げることはできません。
ご質問のとおり、y = interpolate(x_values, y_values, x)
という機能を記述すると、y
の値はx
になりますか?基本的な考え方は、次の手順を実行します。
x
を含む間隔を定義x_values
内の値のインデックスを検索します。たとえば、あなたの例のリストを持つx=3
ために、含む区間は[x1,x2]=[2.5,3.4]
だろう、とインデックスはi1=1
、i2=2
dy/dx
)(y_values[i2]-y_values[i1])/(x_values[i2]-x_values[i1])
することにより、この区間の勾配を計算になります。x
の値は、x1
の値と、スロープにx1
の距離を掛けた値になりました。あなたはさらにx
がx_values
の区間外にある、のいずれか、それは誤りだ、またはあなたが「後方」補間することができ、傾きが最後の/最初の間隔と同じであると仮定した場合に何が起こるかを決定する必要があります。
これは役に立ちましたか、より具体的なアドバイスが必要でしたか?
は私はむしろエレガント溶液(私見)をアップ考え、私はそれ転記抵抗することはできません。私はキックしないであろうように、整数除算float
(パイソン< = 2.7)にマップ
from bisect import bisect_left
class Interpolate(object):
def __init__(self, x_list, y_list):
if any(y - x <= 0 for x, y in zip(x_list, x_list[1:])):
raise ValueError("x_list must be in strictly ascending order!")
x_list = self.x_list = map(float, x_list)
y_list = self.y_list = map(float, y_list)
intervals = zip(x_list, x_list[1:], y_list, y_list[1:])
self.slopes = [(y2 - y1)/(x2 - x1) for x1, x2, y1, y2 in intervals]
def __getitem__(self, x):
i = bisect_left(self.x_list, x) - 1
return self.y_list[i] + self.slopes[i] * (x - self.x_list[i])
を何かを繰り返すと、x1
,x2
、y1
、y2
はすべて整数です。
self.x_list
で
x
よりも小さい最大の要素のインデックスを見つける(非常に)に
bisect_left
を使用して昇順にソートされているという事実を利用してい
__getitem__
で
。
は次のようにクラスを使用します。
i = Interpolate([1, 2.5, 3.4, 5.8, 6], [2, 4, 5.8, 4.3, 4])
# Get the interpolated value at x = 4:
y = i[4]
私は簡単にするため、ここですべての境界条件を扱っていませんでした。そのままで、x < 1
のi[x]
は、(2.5、4)から(1,2)までの直線がマイナスの無限大に伸びたように機能し、x == 1
またはx > 6
のi[x]
はIndexError
になります。すべてのケースでIndexErrorを上げる方が良いでしょうが、これは読者の練習として残されています。:)
私は '__getitem__'の代わりに' __call__'を使うのが一般的です。通常は補間*関数*です。 – Dave
import scipy.interpolate
y_interp = scipy.interpolate.interp1d(x, y)
print y_interp(5.0)
scipy.interpolate.interp1d
エラー状態を処理するために線形補間を行い、カスタマイズすることができます。
解決策はPython 2.7では機能しませんでした。 x要素の順序を確認する際にエラーが発生しました。代わりに端をオフに外挿するの
from bisect import bisect_left
class Interpolate(object):
def __init__(self, x_list, y_list):
if any([y - x <= 0 for x, y in zip(x_list, x_list[1:])]):
raise ValueError("x_list must be in strictly ascending order!")
x_list = self.x_list = map(float, x_list)
y_list = self.y_list = map(float, y_list)
intervals = zip(x_list, x_list[1:], y_list, y_list[1:])
self.slopes = [(y2 - y1)/(x2 - x1) for x1, x2, y1, y2 in intervals]
def __getitem__(self, x):
i = bisect_left(self.x_list, x) - 1
return self.y_list[i] + self.slopes[i] * (x - self.x_list[i])
、あなたがy_list
のエクステントを返すことができます:私はそれを動作させるためにこれにコードを変更する必要がありました。ほとんどの場合、アプリケーションは正常に動作し、Interpolate[x]
はx_list
になります。端から外挿する(おそらく)線形の影響は、データが正常に動作していると誤認する可能性があります。
x_list
外の値のために問題を警告する(
x_list
と
y_list
の内容で囲まれた)非線形結果を返す
。 (非線形入力を与えられたとき、リニア動作がバナナを行く!)
x_list
のInterpolate[x]
外のためy_list
のエクステントを返すも、あなたの出力値の範囲を知っていることを意味します。 x
に基づいて推定すると、x_list[0]
またはx
よりもはるかに大きく、x_list[-1]
よりもはるかに大きくなる場合、結果が予想した値の範囲外になる可能性があります。
def __getitem__(self, x):
if x <= self.x_list[0]:
return self.y_list[0]
elif x >= self.x_list[-1]:
return self.y_list[-1]
else:
i = bisect_left(self.x_list, x) - 1
return self.y_list[i] + self.slopes[i] * (x - self.x_list[i])
私は '__getitem__'の代わりに' __call__'を使うのが一般的です。通常は補間*関数*です。 – Dave
これは...簡単ではありません。何を試しましたか? – zellio
-1これはあまりにも一般的です。あなたはどのようにプログラムするか、またはPythonでアルゴリズムを行う方法を理解していないのですか? – steabert
さて、私は新しい学習者であり、話すために自分自身を深いところに投げ込んでしまった。 アルゴリズムで 'for'または 'if'文を使用することを考えていました。だからxの数多くの範囲の間。 – Helpless