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

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

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

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

NumPy

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

Python 3.x

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

Python

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

Q&A

解決済

1回答

721閲覧

python for 分の高速化がしたいです…!

Rika_Chan

総合スコア1

for

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

NumPy

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

Python 3.x

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

Python

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

0グッド

1クリップ

投稿2022/09/06 13:54

編集2022/09/07 11:40

このコードを高速にしたいのですが、for文を使わずに書く書き方が分かりません。
numbaやcythonも試したのですが、全然ダメでした・・・
少しでも早くするにはどうやってコードを改良したらいいでしょうか。
ご教授よろしくお願いいたします。

def func1(N, n): a = np.sort(np.random.choice((np.arange(N)+1), size=n, replace=False)) b = np.array([a[0]] + np.diff(a).tolist() + [N+1-a[-1]]) b = b/(N+1) h = 1 + sum( np.log(b) * b ) / np.log( n + 1 ) return h def func2(N, M, n): H = [] for m in nb.prange(M): h = func1(N = N, n = n) H.append(h) hhh = np.quantile(H, q = 1-0.05) return hhh func2(10000, 20000, 100)

※実行に3.3秒ほどかかっています

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

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

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

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

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

can110

2022/09/06 14:11

インデントがなくなっているのでコードはコードブロックで囲んでください。 また、そのコードの意図(どういうことをやりたいか)を記載ください。
meg_

2022/09/06 14:14

コードは「コードの挿入」で記入してください。
jbpb0

2022/09/06 14:41

pythonのコードの一番最初の行のすぐ上に ```python だけの行を追加してください また、pythonのコードの一番最後の行のすぐ下に ``` だけの行を追加してください または、 https://teratail.storage.googleapis.com/uploads/contributed_images/56957fe805d9d7befa7dba6a98676d2b.gif を見て、そのようにしてみてください 現状、コードがとても読み辛いです 質問にコードを載せる際に上記をやってくれたら、他人がコードを読みやすくなり、コードの実行による現象確認もやりやすくなるので、回答されやすくなります
Rika_Chan

2022/09/07 11:42

コードを書き直しました!見づらくて大変申し訳ありませんでした。 これは経験分布から検定を行う為に使用しているコードの一部になります。 この部分が遅くて改善しようとしていたのですが、どうにもうまくいきませんでした・・・ よろしくお願いいたします。
meg_

2022/09/07 12:13 編集

コード中の「nb」とは何でしょうか?(numbaでしょうか?)
meg_

2022/09/07 12:17 編集

> ※実行に3.3秒ほどかかっています 当方では0.2秒ほどでした。(Windows11、python 3.9)質問者さんのOS、マシンスペック等は何でしょうか?
Rika_Chan

2022/09/07 16:04

失礼いたしました。nbはnumbaです。 マシンスペックはwindows11, python3.9, core i7-8700です。 vscodeのipynb形式で実行しています。 実行して頂きありがとうございます。 0.2秒ですか…私のPCの何かが邪魔しているのでしょうか…
bsdfan

2022/09/08 05:58

numpy.random.choice() の replace=False は、大きな配列では遅くなるようです。 https://zenn.dev/ymd_h/articles/eea7e22ab95c9a こちらに書かれている numpy.random.Generator.choice() を試してみると、 3.9秒かかっていたのが1.2秒ぐらいまでは速くなりました。(google colabの無料環境)
tmp

2022/09/09 03:16

乱数生成に一番時間がかかっていると思いますが、そもそも、このプログラムがその乱数の性質を分析するものなら、「乱数を変えて」は、意味のない提案になってしまう。 このプログラムのもとになっている仕様や目的が必要だと思います。 そうすれば、私には無理そうですがもっと速いアルゴリズムを提案してくれる人もいるかもしれない。
guest

回答1

0

ベストアンサー

1次元の計算をforで繰り返すかわりに、最初に2次元のデータを作って、一括で計算するように書いてみました。
最初のchoiceする部分は、内包(for)を使って書くしかなさそうです。
手元の環境だと、元のものより1桁ぐらい速くなりました。

python

1def func3(N, M, n): 2 rng = np.random.default_rng() 3 a = np.array([rng.choice(N, n, replace=False) for _ in range(M)]) + 1 4 a.sort(axis=1) 5 b = np.diff(a, axis=1, prepend=0, append=N+1) / (N + 1) 6 h = 1 + np.sum(np.log(b) * b, axis=1) / np.log(n + 1) 7 hhh = np.quantile(h, q=1-0.05) 8 return hhh

途中の計算誤差の影響で、元のものと全く同じ値にはなりません。(同じ乱数シードにした場合でも)
(sumとnp.sumの違いによるものっぽいです)

投稿2022/09/08 08:34

編集2022/09/09 01:59
bsdfan

総合スコア4918

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

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

Rika_Chan

2022/09/10 07:13

ありがとうございます!元のコードの何倍も早くなりました! こんなやり方があったんですね…!勉強になりましたm(__)m
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.30%

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

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

質問する

関連した質問