2009-05-24 10 views
6

テーブル1と同様の20以上のテーブルがあります。すべての文字は実際の値を表しています。Pythonのデータ補間を容易にするデータストレージ

Table 1: 
$/cars |<1 | 2 | 3 | 4+ 
<10,000 | a | b | c | d 
20,000 | e | f | g | h 
30,000 | i | j | k | l 
40,000+ | m | n | o | p 

ユーザー入力は、たとえば、f、g、j、およびkの間の値である(2.4、24594)です。 この双線形補間を計算するPythonの関数定義と擬似コードは、次のとおりです。

def bilinear_interpolation(x_in, y_in, x_high, x_low, y_low, y_high): 
    # interpolate with respect to x 
    # interpolate with respect to y 
    # return result 

は、どのように私は(ファイル、辞書、タプルのタプル、またはリストの辞書)表1からのデータを格納する必要があるので、私は最も効率的かつ正確に双一次補間を行うことができますか?

答えて

7

私が考えることができる、そして標準ライブラリに制限されていない最も計算効率の良いソリューションが必要な場合は、scipy/numpyをお勧めします。まず、a..p配列を2次元numpy配列として格納し、次に$ 4k-10k配列と1〜4配列を1D numpy配列として格納します。両方の1D配列が単調増加している場合はscipyのinterpolate.interp1dを使用し、そうでない場合はinterpolate.bsplrep(二変量スプライン表現)を使用します。または、あなた自身で書くことができ、scipyを気にしないでください。ここではいくつかの例は以下のとおりです。

# this follows your pseudocode most closely, but it is *not* 
# the most efficient since it creates the interpolation 
# functions on each call to bilinterp 
from scipy import interpolate 
import numpy 
data = numpy.arange(0., 16.).reshape((4,4)) #2D array 
prices = numpy.arange(10000., 50000., 10000.) 
cars = numpy.arange(1., 5.) 
def bilinterp(price,car): 
    return interpolate.interp1d(cars, interpolate.interp1d(prices, a)(price))(car) 
print bilinterp(22000,2) 

私がチェックした最後の時間(2007年っぽいからscipyのダウンロードのバージョンは)それだけで、xとyの単調に増加する配列のために働いていた)

この4×4アレイのような小さなアレイについて私はあなたがこれを使いたいと思う: http://docs.scipy.org/doc/scipy/reference/generated/scipy.interpolate.bisplrep.html#scipy.interpolate.bisplrep もっと面白い形の表面を扱い、関数は一度しか作成する必要がない。大規模な配列の場合、これは(interp1dと同じ制限があるかどうかはわかりませんが)これが欲しいと思います: http://docs.scipy.org/doc/scipy/reference/generated/scipy.interpolate.interp2d.html#scipy.interpolate.interp2d しかし、上記の例の3つの配列とは異なる、より冗長なデータ構造が必要です。

+0

私は同様の問題がありますが、O(ログn)でそれを解読できません –

+0

私はすでに私のアプリケーションでnumpyを使用しているので、私はこれが好きです:Dありがとう – dassouki

0

ユースケースが特に奇妙になるような双線形補間は特別なことはありません。 2つのルックアップ(完全な行/列の記憶単位の場合)または4つのルックアップ(アレイタイプの記憶の場合)を行うだけです。最も効率的な方法は、アクセスパターンとデータの構造によって異なります。

あなたの例が本当に代表的なものであれば、合計16のエントリがありますが、あなたはそれを保存することができますし、どんな種類の正常な負荷に対しても十分に速いでしょう。

3

最初の列の並べ替えられたリストを保持し、標準ライブラリのbisectモジュールを使用して値を検索します。これは、すぐ下位のインデックスとすぐ上のインデックスを取得する最適な方法です。他のすべての列は、これと並行して別のリストとして保持することができます。

関連する問題