不規則な(長方形ではない)lon/latグリッドと、lon/lat座標の点群があります。数値的な理由から少しずれている可能性があります)。今、対応するlon/lat点のインデックスが必要です。非長方形の2Dグリッド上の最も近い点のインデックスを効率的に見つける
私はこれを行う関数を書いていますが、それは本当に遅いです。
def find_indices(lon,lat,x,y):
lonlat = np.dstack([lon,lat])
delta = np.abs(lonlat-[x,y])
ij_1d = np.linalg.norm(delta,axis=2).argmin()
i,j = np.unravel_index(ij_1d,lon.shape)
return i,j
ind = [find_indices(lon,lat,p*) for p in points]
numpy/scipyには、優れた(さらに速い)ソリューションがあると確信しています。私はすでにかなりたくさんのグーグルで探偵してきましたが、答えは今まで私を逃しています。
対応する(最も近い)ポイントのインデックスを効率的に見つける方法を教えてください。
PS:この質問は別のもの(click)から現れました。
編集:ここでは、大局的にこのソリューションともDivakarの答えから1を配置するには
def find_indices(points,lon,lat,tree=None):
if tree is None:
lon,lat = lon.T,lat.T
lonlat = np.column_stack((lon.ravel(),lat.ravel()))
tree = sp.spatial.cKDTree(lonlat)
dist,idx = tree.query(points,k=1)
ind = np.column_stack(np.unravel_index(idx,lon.shape))
return [(i,j) for i,j in ind]
です:@Cong馬の答えに基づくソリューション
、私は次の解決策を見つけました私は(上記のリンクを参照)find_indicesを使用して(と、それはスピードの面でのボトルネックだ)いている機能のいくつかのタイミング:
spatial_contour_frequency/pil0 : 331.9553
spatial_contour_frequency/pil1 : 104.5771
spatial_contour_frequency/pil2 : 2.3629
spatial_contour_frequency/pil3 : 0.3287
私の最初のアプローチは、pil1
Divakar'sであり、pil2
/pil3
である。上記の最終的な解決策では、ツリーは、オンザフライでpil2
で作成される。ループの反復ごとにfind_indices
が呼び出されます)、一度だけpil3
(詳細は他のスレッドを参照してください)。私の最初のアプローチのDivakarの洗練は私に3倍のスピードアップをもたらしますが、cKDTreeはこれを全く新しいレベルまで50倍のスピードアップで実現します!そして、関数から木の作成を動かすことは事をより速くします。
スクリプトでは、 'find_indices'を呼び出すたびに新しいツリーを作成しています。あなたのグリッドがコール全体で固定されている場合、同じツリーを何度も何度も繰り返し作成する時間を無駄にしています。実際には、このツリーの構築はこの関数の中で最も遅い呼び出しです。 –
はい、私は気付きました、それは私がこの瞬間に取り組んでいることです。 ;)私はそれに応じて答えを更新します。発言をありがとう。 – flotzilla