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

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

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

for文は、様々なプログラミング言語で使われている制御構造です。for文に定義している条件から外れるまで、for文内の命令文を繰り返し実行します。

Python

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

ArrayList

Java用のタグです。arrayListはListインターフェースを実装した、リサイズ可能な配列用クラスです。

Q&A

解決済

1回答

3668閲覧

効率よく粒子の密度を求める方法

Masaru14

総合スコア10

for

for文は、様々なプログラミング言語で使われている制御構造です。for文に定義している条件から外れるまで、for文内の命令文を繰り返し実行します。

Python

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

ArrayList

Java用のタグです。arrayListはListインターフェースを実装した、リサイズ可能な配列用クラスです。

0グッド

0クリップ

投稿2017/07/28 02:34

###与えられた多数の粒子の位置情報から粒子密度を求めたい。
粒子の位置情報を乱数で与え、そこからグリッドで分割された(一次元)空間における粒子の密度を推定するプログラムを作成しています。
一つの考えとしてfor文を使えば密度を推定することができるのですが、計算速度があまり速くありません。for文を使わずに密度を推定する方法があるでしょうか?

###for文を用いた方法

python

1import numpy as np 2import matplotlib.pyplot as plt 3nop=100 #粒子数 4nx =10 #空間グリッド数 5dx =1 #グリッド幅 6lx =nx*dx #空間長 7xx =np.arange(nx) #空間をグリッドに分割 8xp =np.random.rand(nop)*lx #粒子位置を乱数で生成 9ds =np.zeros(nx) #密度、0クリア 10 11for ip in range(nop): 12 ix=int(xp[ip]/dx) #粒子をグリッド状に分配 13 ds[ix]=ds[ix]+1 #グリッド上の粒子を数える 14 15plt.subplot(2,1,1); plt.plot(xp,np.ones(nop),'.') 16plt.subplot(2,1,2); plt.plot(xx,ds,'-o') 17plt.show()

上記プログラムの実行結果
この方法を使って粒子数を10**6個にしたところ計算時間が3.05秒でした。

###for文を使わない方法(失敗)
計算時間がかかっているfor文を使わずに上記のプログラムと同じことをしたいと思っています。そこで以下のようなプログラムを作製したのですが、うまく行きませんでした。なにかいい方法があるのでしょうか?それともこの場合はfor文を使わざるおえないのでしょうか?

python

1import numpy as np 2import matplotlib.pyplot as plt 3nop=100 #粒子数 4nx =10 #空間グリッド数 5dx =1 #グリッド幅 6lx =nx*dx #空間長 7xx =np.arange(nx) #空間をグリッドに分割 8xp =np.random.rand(nop)*lx #粒子位置を乱数で生成 9ds =np.zeros(nx) #密度、0クリア 10#for ip in range(nop): 11ix=np.int_(xp/dx) #粒子をグリッド状に分配 12ds[ix]=ds[ix]+1 #グリッド上の粒子を数える 13 14plt.subplot(2,1,1); plt.plot(xp,np.ones(nop),'.') 15plt.subplot(2,1,2); plt.plot(xx,ds,'-o') 16plt.show()

上記プログラム結果

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

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

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

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

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

guest

回答1

0

ベストアンサー

単純に numpy.histogram()を使うとよいのではないでしょうか。

https://docs.scipy.org/doc/numpy/reference/generated/numpy.histogram.html

python

1ds = np.histogram(xp/dx, bins=np.arange(nx+1))[0]

【補足】

コメントにて依頼があったので、他の方法を何点か

Python

1ds =np.zeros(nx) 2for i in np.arange(nx): 3 d = xp/dx 4 ds[i] = ((i <= d) & (d < i+1)).sum()

Python

1ds =np.zeros(nx) 2for i in np.arange(nx): 3 ds[i] = ((xp/dx).astype(int) == i).sum()

Python

1ds = np.bincount((xp/dx).astype(int))

投稿2017/07/28 03:00

編集2017/07/28 04:34
magichan

総合スコア15898

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

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

Masaru14

2017/07/28 04:01

ありがとうございます!計算速度が10倍ほど改善されました。 後々、線形補間や境界条件を加えたいと考えており、外部関数を使うのを控えて柔軟なプログラムを作りたいのですが、配列操作だけで上記のプログラムを作るのは不可能でしょうか?
magichan

2017/07/28 04:39

> 配列操作だけで 何処までを許容しているのかがよくわからないのですが(そもそもデータがnumpy配列に入っているので)、 とりあえずデータ全てをループで回すのではなくグリッド毎にループを回すようにすると、それほど遅くなることはないかと思います。 一応、回等欄に幾つか方法を追加したので確認ください。
Masaru14

2017/07/28 07:51

ありがとうございます。勉強させていただきます。。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問