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

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

ただいまの
回答率

88.57%

for文、リストを多用しているコードを高速化したい

解決済

回答 2

投稿

  • 評価
  • クリップ 0
  • VIEW 675

aine_

score 22

pythonでコードをつくったのですが回るのが非常に遅くてこまっています。
高速化したいコードは以下の通りです。稚拙なコードですがご教授おねがいします。

import h5py
import numpy as np
import matplotlib.pyplot as plt
kekka = []

#hdfファイルからデータを読み取る
# %d:各時間のデータ
for b in range (0,40000,100):
    hdf5 = h5py.File("C:file_%d.hdf5"%(b), 'r')
    list_x=(hdf5["particles/fluid/arrays/x"].value.tolist())
    list_y=(hdf5["particles/fluid/arrays/y"].value.tolist())
    list_z=(hdf5["particles/fluid/arrays/z"].value.tolist())
    list_p=(hdf5["particles/fluid/arrays/p"].value.tolist())
    #z座標(高さ)の条件をわける
    Z=[]
    zkiriwake = [0.001*x for x in range(1,2001,20)]
    for u in zkiriwake:
        zyouso = [j for j, takasa in enumerate(list_z) if (u+0.02)>=takasa>=(u)]
        Z.append(zyouso)

    #x,y座標の条件わけ
    r = [i for i, (x, y) in enumerate(zip(list_x, list_y)) if 0.15*0.15>=((x-7.0)**2+y**2) and x>=7.0 ]
    y1 = [i for i, y in enumerate(list_y) if -0.8>=y>=-0.10]
    y2 = [i for i, y in enumerate(list_y) if -0.06>=y>=-0.08]
    y3 = [i for i, y in enumerate(list_y) if -0.04>=y>=-0.06]
    y4 = [i for i, y in enumerate(list_y) if -0.02>=y>=-0.04]
    y5 = [i for i, y in enumerate(list_y) if 0>=y>=-0.02]
    y6 = [i for i, y in enumerate(list_y) if 0.02>=y>=0]
    y7 = [i for i, y in enumerate(list_y) if 0.04>=y>=0.02]
    y8 = [i for i, y in enumerate(list_y) if 0.06>=y>=0.04]
    y9 = [i for i, y in enumerate(list_y) if 0.08>=y>=0.06]
    y10 = [i for i, y in enumerate(list_y) if 0.10>=y>=0.08]

  #それぞれの高さについて、指定した位置の圧力平均をとりモーメント化  
    power1=[]
    M = [0.01*x for x in range (1,201,2)]#モーメント計算に使用するうでの長さ
    for h in Z:
        hani1 = set (h) & set (r) & set (y1)
        hani2 = set (h) & set (r) & set (y2)
        hani3 = set (h) & set (r) & set (y3)
        hani4 = set (h)  & set (r) & set (y4)
        hani5 = set (h)  & set(r) & set (y5) 
        hani6 = set (h) & set (r) & set (y6) 
        hani7 = set (h) & set (r) & set (y7) 
        hani8 = set (h) & set (r) & set (y8) 
        hani9 = set (h) & set (r) & set (y9) 
        hani10 = set (h) & set (r) & set (y10) 
        p1 = [list_p[i] for i in hani1]
        p2 = [list_p[i] for i in hani2]
        p3 = [list_p[i] for i in hani3]
        p4 = [list_p[i] for i in hani4]
        p5 = [list_p[i] for i in hani5]
        p6 = [list_p[i] for i in hani6]
        p7 = [list_p[i] for i in hani7]
        p8 = [list_p[i] for i in hani8]
        p9 = [list_p[i] for i in hani9]
        p10 = [list_p[i] for i in hani10]
        goukei = np.array([sum(p1),sum(p2),sum(p3),sum(p4),sum(p5),sum(p6),sum(p7),sum(p8),sum(p9),sum(p10)])
        kazu = np.array([len(p1),len(p2),len(p3),len(p4),len(p5),len(p6),len(p7),len(p8),len(p9),len(p10)])
        pp=np.zeros_like(kazu)
        pp[kazu!=0]=goukei[kazu!=0]/kazu[kazu!=0]
        ppp=sum(pp)
        power1.append(ppp)

    moment1 = [x * y for (x, y) in zip(power1, M)]
  #圧力について面積を考慮せず計算していたため最後に面積をかける
    mo = sum(moment1)*0.02*0.02*3.14
    kekka.append(mo)
#グラフ制作
plt.plot(kekka) 
plt.title("moment and time")
plt.xlabel("time[1e-5]")
plt.ylabel("moment[Nm]")
plt.show()


これは粒子がある円柱にぶつかるシミュレーションの、円柱周辺のモーメントを計算するというコードで、高さごとにそれぞれの平面的範囲の圧力平均をモーメント計算するというものです。

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

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

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

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 過去に投稿した質問と同じ内容の質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 2

+2

条件に沿ってインデックスを取って処理するような部分が多いので、そういうところはnumpyのboolean maskやfancy indexなどで書き換える方針にしてみると良いと思います。

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2018/12/06 14:08

    ありがとうございます。その形式も調べてみます。

    キャンセル

checkベストアンサー

+1

まずは、forsetlist_plist_yの出現回数が少なくなるようにコードを書き換えるとそれなりに速くなると思いますよ。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2018/12/06 14:08

    ありがとうございます。その4つが重いのですね

    キャンセル

  • 2018/12/06 15:18

    その4つが重いのではなく、同じものが何回も出現するコードは遅くなりがちというか事が言いたかったんです。

    キャンセル

  • 2018/12/06 15:23

    なるほど、浅学で申し訳ないです。ありがとうございます。

    キャンセル

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

  • ただいまの回答率 88.57%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る