20

温度データを4次元(緯度、経度、高度、時間)で線形補間する必要があります。
ポイントの数はかなり多く(360x720x50x8)、データ範囲内の空間と時間の任意のポイントで温度を計算する高速な方法が必要です。

使用してみscipy.interpolate.LinearNDInterpolatorましたが、三角測量にQhullを使用すると、長方形のグリッドでは非効率になり、完了するまでに数時間かかります。

このSciPyチケットinterp1dを読むことにより、ソリューションは、標準を使用してより多くのデータポイントを計算し、新しいデータセットで「最近傍」アプローチを使用する新しいnd補間器を実装しているように見えました。

ただし、これには再び長い時間がかかります(分)。

長方形のグリッド上のデータを、数分もかからずに4次元で補間する簡単な方法はありますか?

高密度のポイントを計算せずにinterp1d4回使用することを考えましたが、ユーザーが座標を使用して呼び出すようにしましたが、これを行う方法について頭を悩ませることはできません。

そうでなければ、私のニーズに固有の独自の4D補間器を作成することは、ここでのオプションでしょうか?

これをテストするために私が使用しているコードは次のとおりです。

使用scipy.interpolate.LinearNDInterpolator

import numpy as np
from scipy.interpolate import LinearNDInterpolator

lats = np.arange(-90,90.5,0.5)
lons = np.arange(-180,180,0.5)
alts = np.arange(1,1000,21.717)
time = np.arange(8)
data = np.random.rand(len(lats)*len(lons)*len(alts)*len(time)).reshape((len(lats),len(lons),len(alts),len(time)))

coords = np.zeros((len(lats),len(lons),len(alts),len(time),4))
coords[...,0] = lats.reshape((len(lats),1,1,1))
coords[...,1] = lons.reshape((1,len(lons),1,1))
coords[...,2] = alts.reshape((1,1,len(alts),1))
coords[...,3] = time.reshape((1,1,1,len(time)))
coords = coords.reshape((data.size,4))

interpolatedData = LinearNDInterpolator(coords,data)

使用scipy.interpolate.interp1d

import numpy as np
from scipy.interpolate import LinearNDInterpolator

lats = np.arange(-90,90.5,0.5)
lons = np.arange(-180,180,0.5)
alts = np.arange(1,1000,21.717)
time = np.arange(8)
data = np.random.rand(len(lats)*len(lons)*len(alts)*len(time)).reshape((len(lats),len(lons),len(alts),len(time)))

interpolatedData = np.array([None, None, None, None])
interpolatedData[0] = interp1d(lats,data,axis=0)
interpolatedData[1] = interp1d(lons,data,axis=1)
interpolatedData[2] = interp1d(alts,data,axis=2)
interpolatedData[3] = interp1d(time,data,axis=3)

ご助力ありがとうございます!

4

4 に答える 4

13

リンクした同じチケットに、テンソル積補間と呼ばれるものの実装例があり、への再帰呼び出しをネストする適切な方法を示していますinterp1dkind='linear'のデフォルトパラメータを選択した場合、これは4次補間と同等ですinterp1d

これで十分かもしれませんが、これは線形補間ではなく、双線形補間に関するウィキペディアのエントリからのこの画像が示すように、補間関数には高次の項があります。

ここに画像の説明を入力してください

これはあなたが求めているものには十分かもしれませんが、三角形分割された、実際には区分的に線形の、中間配置が好まれるアプリケーションがあります。これが本当に必要な場合は、qhullの速度低下を回避する簡単な方法があります。

LinearNDInterpolatorセットアップが完了したら、特定のポイントの補間値を作成するための2つのステップがあります。

  1. ポイントがどの三角形(あなたの場合は4Dハイパーテトラヘドロン)の内側にあるかを把握し、
  2. 頂点を基準にしたポイントの重心座標を重みとして使用して内挿します。

おそらく重心座標を台無しにしたくないので、そのままにしておくことをお勧めしLinearNDInterpolatorます。しかし、あなたは三角測量についていくつかのことを知っています。ほとんどの場合、通常のグリッドがあるため、各ハイパーキューブ内の三角形分割は同じになります。したがって、単一の値を補間するには、最初にポイントがどのサブキューブにあるかを判別し、LinearNDInterpolatorそのキューブの16の頂点でを構築し、それを使用して値を補間することができます。

from itertools import product

def interpolator(coords, data, point) :
    dims = len(point)
    indices = []
    sub_coords = []
    for j in xrange(dims) :
        idx = np.digitize([point[j]], coords[j])[0]
        indices += [[idx - 1, idx]]
        sub_coords += [coords[j][indices[-1]]]
    indices = np.array([j for j in product(*indices)])
    sub_coords = np.array([j for j in product(*sub_coords)])
    sub_data = data[list(np.swapaxes(indices, 0, 1))]
    li = LinearNDInterpolator(sub_coords, sub_data)
    return li([point])[0]

>>> point = np.array([12.3,-4.2, 500.5, 2.5])
>>> interpolator((lats, lons, alts, time), data, point)
0.386082399091

これは、ベクトル化されたデータでは機能しません。これは、LinearNDInterpolator可能なすべてのサブキューブに対してを格納する必要があるためです。おそらく、全体を三角測量するよりも高速ですが、それでも非常に低速です。

于 2013-01-02T12:58:03.527 に答える
5

scipy.ndimage.map_coordinates は、均一なグリッド(すべてのボックスが同じサイズ)用の優れた高速補間器です。明確な説明については、SOのmultivariate-spline-interpolation-in-python-scipyを参照してください。

不均一な長方形グリッドの場合、単純なラッパー Intergridは、不均一なグリッドを均一なグリッドにマッピング/スケーリングしてから、map_coordinatesを実行します。あなたのような4dテストケースでは、クエリごとに約1μ秒かかります。

Intergrid: 1000000 points in a (361, 720, 47, 8) grid took 652 msec
于 2013-01-21T15:46:12.410 に答える
2

非常によく似たものについては、Scientific.Functions.Interpolation.InterpolatingFunctionを使用します。

    import numpy as np
    from Scientific.Functions.Interpolation import InterpolatingFunction

    lats = np.arange(-90,90.5,0.5)
    lons = np.arange(-180,180,0.5)
    alts = np.arange(1,1000,21.717)
    time = np.arange(8)
    data = np.random.rand(len(lats)*len(lons)*len(alts)*len(time)).reshape((len(lats),len(lons),len(alts),len(time)))

    axes = (lats, lons, alts, time)
    f = InterpolatingFunction(axes, data)

これで、ユーザーに任せて、InterpolatingFunction座標を使用してを呼び出すことができます。

>>> f(0,0,10,3)
0.7085675631375401

InterpolatingFunction統合やスライスなどの優れた追加機能があります。

ただし、補間が線形であるかどうかはわかりません。調べるには、モジュールソースを調べる必要があります。

于 2013-07-19T15:07:59.603 に答える
0

このアドレスを開くことができず、このパッケージに関する十分な情報を見つけることができません

于 2020-05-11T14:49:22.133 に答える