質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.31%
NumPy

NumPyはPythonのプログラミング言語の科学的と数学的なコンピューティングに関する拡張モジュールです。

Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

Q&A

解決済

2回答

1336閲覧

np.gradientを用いて地形の傾斜を計算したい

gantakun

総合スコア16

NumPy

NumPyはPythonのプログラミング言語の科学的と数学的なコンピューティングに関する拡張モジュールです。

Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

0グッド

0クリップ

投稿2022/03/21 06:43

np.gradientを用いて地形の傾斜を計算したい

現在,地形の傾斜のデータをPythonを用いて取得しようとしています.
計算の高速化のため,for文を使用せず,np.gradientを用いて,
一括で傾斜する計算する方法を考えているのですが,
それがわからないため質問させていただきました.

実現したいこと

以下の傾斜を求める手法をnp.gradientで実現したいと考えています.
これはppにおける傾斜を該当グリッドの周囲8方向から取得するものです.
イメージ説明

この方法を実現するために,以下のようなfor文を入れたコードを作成しましたが,
for文を用いずに傾斜を求める手法をご教授頂ければと思います.

該当のソースコード

Python

1#モジュールのインポート 2import numpy as np 3import math 4 5#標高データの準備 6current_dem = np.array([[1,2,3,4], [5,7,9,10], [8,15,12,9], [8,5,3,1]]) 7 8#傾斜の格納要配列の準備 9value_slope = np.zeros((4, 4)) 10value_slope[:,:] = np.nan 11 12#標高(グリッドデータ)のx,y方向の間隔 13DX = 1 14DY = 1 15 16#傾斜の計算 17for i in range(4): 18 for j in range(4): 19 if i != 0 and j != 0 and i != 3 and j != 3: 20 21 pp = current_dem[i][j] 22 23 d1 = current_dem[i+1][j-1] 24 25 d2 = current_dem[i+1][j] 26 27 d3 = current_dem[i+1][j+1] 28 29 d4 = current_dem[i][j-1] 30 31 d6 = current_dem[i][j+1] 32 33 d7 = current_dem[i-1][j-1] 34 35 d8 = current_dem[i-1][j] 36 37 d9 = current_dem[i-1][j+1] 38 39 xx = (d1+d4+d7-(d3+d6+d9))/(6*DX) 40 yy = (d7+d8+d9-(d1+d2+d3))/(6*DY) 41 42 value_slope[i, j] = math.sqrt(xx*xx + yy*yy) 43 44print(value_slope) 45#[[ nan nan nan nan] 46 #[ nan 5.11262055 4.50308536 nan] 47 #[ nan 0.97182532 3.06412939 nan] 48 #[ nan nan nan nan]]

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

回答2

0

ベストアンサー

今回のような計算で、forループをなくして高速化をするのが目的なら畳み込みを使うのがいいと思います。numpyには二次元の畳み込みの関数はないので、scipyのconvolve2dを使います。
(scipyなしでもできますが、scipyを使ったほうが速度面でも有利じゃないかと)

python

1import numpy as np 2from scipy.signal import convolve2d 3 4#標高データの準備 5current_dem = np.array([[1,2,3,4], [5,7,9,10], [8,15,12,9], [8,5,3,1]]) 6 7#標高(グリッドデータ)のx,y方向の間隔 8DX = 1 9DY = 1 10 11grad_x = np.array([[-1, 0, 1], [-1, 0, 1], [-1, 0, 1]]) / (6 * DX) 12grad_y = np.array([[-1, -1, -1], [0, 0, 0], [1, 1, 1]]) / (6 * DY) 13 14xx = convolve2d(current_dem, grad_x, mode='same', boundary='fill', fillvalue=np.nan) 15yy = convolve2d(current_dem, grad_y, mode='same', boundary='fill', fillvalue=np.nan) 16 17value_slope = np.sqrt(xx * xx + yy * yy) 18print(value_slope)

numpy.gradient を使ってやるなら、こんな感じではないでしょうか。
(最終的な計算結果には影響しないですが、上の畳み込みの場合とxx, yyの符号が違っているので注意ください)

python

1ey, ex = np.gradient(current_dem, DY, DX) 2 3xx = (ex[:-2, 1:-1] + ex[1:-1, 1:-1] + ex[2:, 1:-1]) / 3 4yy = (ey[1:-1, :-2] + ey[1:-1, 1:-1] + ey[1:-1, 2:]) / 3 5 6# 上の部分は sliding_window_view を使って下記のようにも書けます 7#from numpy.lib.stride_tricks import sliding_window_view 8#xx = np.mean(sliding_window_view(ex[:, 1:-1], 3, axis=0), axis=-1) 9#yy = np.mean(sliding_window_view(ey[1:-1, :], 3, axis=1), axis=-1) 10 11value_slope = np.full(current_dem.shape, np.nan) 12value_slope[1:-1, 1:-1] = np.sqrt(xx * xx + yy * yy) 13print(value_slope)

投稿2022/03/22 05:57

編集2022/03/22 06:01
bsdfan

総合スコア4899

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

gantakun

2022/03/22 06:59

回答ありがとうございます.参考にさせていただきます.scipyは使用した経験がなかったのですが, これを機に学んでみたいと思います.
guest

0

実質的に for ループと等価なので参考までにどうぞ。

python

1#傾斜の計算 2def calc_slope(i, j): 3 xx = np.sum(current_dem[i-1,j-1:j+2] - current_dem[i+1,j-1:j+2])/(6*DX) 4 yy = np.sum(current_dem[i-1:i+2,j-1] - current_dem[i-1:i+2,j+1])/(6*DX) 5 value_slope[i, j] = np.sqrt(xx**2 + yy**2) 6 7r, c = current_dem.shape 8prd = np.dstack(np.meshgrid(range(1,r-1), range(1,c-1))).reshape(-1, 2).T 9np.vectorize(calc_slope)(*prd)

投稿2022/03/21 11:06

melian

総合スコア21118

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

gantakun

2022/03/22 07:00

回答ありがとうございます.参考にさせていただきます.
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.31%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問