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

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

新規登録して質問してみよう
ただいま回答率
85.50%
Python 3.x

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

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

Q&A

1回答

325閲覧

多重ループを使わずに処理を実装したい

samyu

総合スコア11

Python 3.x

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

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

0グッド

1クリップ

投稿2018/01/25 06:39

編集2022/01/12 10:55

前提・実現したいこと

まず、配列の指定した要素とその配列の特定の値を持っている要素、それぞれとのユークリッド距離をとります。その後ユークリッド距離の平均をとり、平均より内側にある特定の値を持っている要素を全て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()

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

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

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

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

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

KSwordOfHaste

2018/01/25 07:38

euclideanの対象にしている変数aですけど・・・dst[50][50]とすると中心付近にある特定の数値(1~4)のうち一つ、になるのでそのスカラー値と対象の座標[y,x]との距離を計算するというのは間違いではないでしょうか?中心との距離を計算するならa=[50,50]などとすべきでは?
samyu

2018/01/25 07:50

おっしゃる通りです。修正しておきます。
LouiS0616

2018/01/25 07:56

当該処理を何度も呼び出すのでしょうか?もしそうならば、距離に関する条件に変化はありませんので、前もって作った『距離マスク』を共用すれば良さそうですが...
can110

2018/01/25 09:29

厳密には a = [49.5,49.5]でしょうか。(=N個 / 2-0.5)奇数個だとぴったりの位置が得られます。
samyu

2018/01/25 10:01

当該処理は何度も呼び出すことを想定しています。また今回は不変でしたが、本来の処理では、呼び出すたびに、配列の大きさと変数「a」の座標は変わるものとしています。
guest

回答1

0

python

1x=np.arange(width).reshape([1,width]) 2y=np.arange(height).reshape([height,1]) 3euclidean=((x-width/2)**2+(y-height/2)**2)**0.5

として、先にユークリッド距離が入ったwidth x heightの行列を作ります。

python

1avg=np.average(euclidean[dst==index]) 2euclidean[(dst==index)*(euclidean<avg)]=0 3num2=np.sum(dst==1) 4num3=np.sum(dst==0)

で「平均」と「平均より内側にある特定の値を持っている要素を全て0にする」と「処理後の1の要素数」と「処理後の0の要素数」を実行or求めることができます。

投稿2018/01/25 08:10

hiro-k

総合スコア902

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

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

can110

2018/01/25 09:32

「euclidean[(dst==index)*(euclidean<avg)]=0」は「dst[(dst==~」が正しいのではないでしょうか? また中央位置の計算も厳密には「(width/2-0.5)」が適切かと思いました。 ループに比べてけた違いに速いですね。
samyu

2018/01/25 10:20 編集

ありがとうございます。申し訳ないのですが1つ質問の訂正があります。質問では配列の中心とのユークリッド距離を取ると書いていましたが、実は処理を呼び出すたび、配列の大きさと変数「a」の座標は変化します。つまり必ずしも、配列の中心との距離を求めるわけではなく、指定したある点と特定の値を持つ要素とのユークリッド距離を取り、平均より内側にある特定の値を持つ要素を全て0にするが正しい質問になります。
hiro-k

2018/01/25 10:31

aの座標が変化するということであれば、その座標を(ax,ay)として、 euclidean=((x-ax)**2+(y-ay)**2)**0.5 で良いかと思います。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

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

ただいまの回答率
85.50%

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

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

質問する

関連した質問