前提・実現したいこと
まず、配列の指定した要素とその配列の特定の値を持っている要素、それぞれとのユークリッド距離をとります。その後ユークリッド距離の平均をとり、平均より内側にある特定の値を持っている要素を全て0にする。という処理を実装しました。
発生している問題・エラーメッセージ
多重ループを多用しているため、配列が大きくなるにつれ、処理が重くなってしまいます。そのため、できるだけ多重ループを使わずに処理を実装しようしているのですが、思ったようにいきません。
該当のソースコード
python
1import numpy as np 2from scipy.spatial import distance 3 4def main(): 5 list = [] 6 index = 1 7 dst = np.random.randint(1, 4, (100, 100)) 8 dst2 = np.ones((100,100)) 9 num1 = len(np.where(dst==1)[0]) 10 print("処理前の1の要素数",num1) 11 height,width = dst2.shape[:2] 12 a = [50,50] 13 14 for y in range(height): 15 for x in range(width): 16 if dst[y][x] == index: 17 b = np.array([y,x]) 18 list.append(distance.euclidean(a,b)) 19 #速度向上のための案 20 #list = np.array([distance.euclidean(a,dst[dst==index])]) 21 22 ave = np.average(list) 23 24 i = 0 25 for y in range(height): 26 for x in range(width): 27 if dst[y][x] == index: 28 i += 1 29 if list[i-1] < ave: 30 dst2[y][x] = 0 31 32 num2 = len(np.where(dst2==1)[0]) 33 print("処理後の1の要素数",num2) 34 num3 = len(np.where(ds2t==0)[0]) 35 print("処理後の0の要素数",num3) 36 37if __name__ == '__main__': 38 main()
euclideanの対象にしている変数aですけど・・・dst[50][50]とすると中心付近にある特定の数値(1~4)のうち一つ、になるのでそのスカラー値と対象の座標[y,x]との距離を計算するというのは間違いではないでしょうか?中心との距離を計算するならa=[50,50]などとすべきでは?
おっしゃる通りです。修正しておきます。
当該処理を何度も呼び出すのでしょうか?もしそうならば、距離に関する条件に変化はありませんので、前もって作った『距離マスク』を共用すれば良さそうですが...
厳密には a = [49.5,49.5]でしょうか。(=N個 / 2-0.5)奇数個だとぴったりの位置が得られます。
当該処理は何度も呼び出すことを想定しています。また今回は不変でしたが、本来の処理では、呼び出すたびに、配列の大きさと変数「a」の座標は変わるものとしています。