2017-12-11 17 views
1

ランダムな場所に緯度、経度、高度の値を持つcsvファイルがあります。私はIDW補間を適用して通常のグリッドを生成したかったのです。最近の検索ではscipy.spatial.cKDTreeを使用し、未知の点で標高値を見つけました。 出力グリッドに寸法(z < 1000 X1000)がある場合、次のコードは正常に機能します。ディメンションが大きくなると、コードは実際には遅くなります。ループのためにをベクトル化して、cKDTreeを使用して削除するのを手伝ってください。ありがとうございました。2つの配列でckdtreeを検索するためのvectorizeループ

## Inverse distance weighted function 
def idw(p, dist, values): 

    dist_pow = np.power(dist, 2) 
    nominator = np.sum(values/dist_pow) 
    denominator = np.sum(1/dist_pow) 
    if denominator > 0: 
     return nominator/denominator 
    else: 
     return none 
## Reading the lat/lon and elevation values from file 
lat = [] 
lon = [] 
ele = [] 

with open('VSKP_ground_dat.csv') as read: 
    csvreader = csv.DictReader(read) 
    for row in csvreader: 
     lat.append(float(row['LAT'])) 
     lon.append(float(row['LON'])) 
     ele.append(float(row['ALT'])) 
xycoord = np.c_[lon,lat] 
ele_arr = np.array(ele) 

## ------------- Creating KDTree 
point_tree = spatial.cKDTree(xycoord, leafsize=25) 
## ------------- Creating empty grid matrix with np.zeros 
xmin, xmax, ymin, ymax = 81.903158, 83.352158, 17.25856, 18.40056 
## --------- Defining resolution 
xres, yres = 0.01, 0.01 

x = np.arange(xmin, xmax, xres) 
y = np.arange(ymin, ymax, yres) 
z = np.zeros((x.shape[0], y.shape[0]), dtype=np.float16) 


for i, val1 in enumerate(x): 
    for j, val2 in enumerate(y): 
     p = np.array([val1, val2]) 
     # points_idx = point_tree.query_ball_point(p, dist_2) 
     distances, points_idx = point_tree.query(p, k=6, eps=0) 
     ele_vals = ele_arr[points_idx] 
     value = idw(p, distances, ele_vals) 
     z[i,j] = value 
+0

'idw'機能が何であるかに基づいていますか? 'for'ループを削除するにはベクトル化する必要があります –

+0

また、変数名が一貫していることを確認してください。私は 'p'と' point'は同じものと思われますと思いますか? –

+0

ありがとうございます。はい、Pと点は同じです(間違い)、IDWは逆距離加重補間関数です。 – psaibharadwaj

答えて

0

まず、最後のインデックス上で動作するようにあなたのidw機能を修正:

def idw(dist, values, p = 2): 
    out = np.empty(dist.shape[:-1]) 
    mask = np.isclose(dist, 0).any(-1) 
    out[mask] = values[np.isclose(dist, 0)]     # should be only one per point 
    dist_pow = np.power(dist[~mask], -p)      # division is costly, do it once 
    nominator = np.sum(values[~mask] * dist_pow, axis = -1) # over mask to prevent divide by zero 
    denominator = np.sum(dist_pow, index = -1) 
    out[~mask] = nominator/denominator 
    return out 

その後、残りはnp.meshgrid出力

x = np.arange(xmin, xmax, xres)       # len i 
y = np.arange(ymin, ymax, yres)       # len j 
xy = np.stack(np.meshgrid(x, y), axis = -1)    # shape(i, j, 2) 
distances, points_idx = point_tree.query(xy, k=6, eps=0) # shape (i, j, 6) 
ele_vals = ele_arr[points_idx]       # shape (i, j, 6) 
z = idw(distances, ele_vals)        # shape (i, j) 
+0

私はspatial.ckdtree.cKDTree.queryを取得しています ValueError:xは長さ2のベクトルで構成する必要がありますが、形状(2,115,145)を持っている必要があります。私は 'lat = [17.749405、17.788955、17.805596、17.817568、....]と' lon = [81.903658,81.940228,81.97914,82.008435,82.009833,82.03696、.....] – psaibharadwaj

+0

を忘れてしまった'np.stack'の' axis'を使って正しい形を得ます。ごめんなさい! –

+0

これは素晴らしい動作します。 IDW関数で 'index'を' axis'に変更し、可能であればIDW関数について詳しく説明してください。助けてくれてありがとう。 – psaibharadwaj

関連する問題