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

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

ただいまの
回答率

88.13%

python コードを高速化したい

受付中

回答 6

投稿 編集

  • 評価
  • クリップ 0
  • VIEW 2,502

score 73

下記のコードを書いたのですが,
ちゃんと計算できるのですが,とてつもなく遅いです.
for文をつかっているからだと思いますが,
なにか良い手立てはないでしょうか.

ちなみに,よみこんでいるファイルは結合すると9000行1列になります.
それをappendしまくり,最後に9000*252行の一列のデータができるので
それをreshapeして9000行252列にしようとしました.

今30分ほど計算してますが
まだi=80程度です.

#!/usr/bin/env python2.7
# coding: utf-8
# test.py
import pandas as pd
import numpy as np
import decimal as dec

pressure_uniq = []
###252点分のprobeファイルをそれぞれ結合する
for i in range(252):
    print(i)
    pressure = []
    pressure1 = pd.read_csv('pressure1/probedata_dome_prs_p'+str(i+1), delim_whitespace=True, comment='#',names=['A', 'B', 'C'])
    pressure2 = pd.read_csv('pressure2/probedata_dome_prs_p'+str(i+1), delim_whitespace=True, comment='#',names=['A', 'B', 'C'])
    pre1 = pressure1['C']
    pre2 = pressure2['C']
    pressure = pd.concat([pre1,pre2])
###多少のかぶりがあるから,ユニークな値のみを抽出
    for x in pressure:
        if x not in pressure_uniq:
            pressure_uniq.append(x)

array_pressure_uniq = np.array(pressure_uniq)
reshape_pressure_uniq = array_pressure_uniq.reshape(252,9000)
np.savetxt('reshape_pressure.csv',reshape,delimiter=',')
  • 気になる質問をクリップする

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

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

    クリップを取り消します

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

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

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

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

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

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

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

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

    質問の評価を下げる

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

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

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

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

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

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

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

    詳細な説明はこちら

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

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

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

回答 6

+4

遅いのは実行時間というより、ファイルを500個以上読み込むから、じゃないでしょうか。
他の処理をさせずにファイル読み込みのみで実行時間を見てみれば。

投稿

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

0

pressureに含まれる値にかぶりが少ない(ほとんどがユニークな値)なのだとすると、以下の2重のforループの計算量のオーダーは、pressureに含まれる値の個数の二乗程度と考えられます。
どのぐらいの個数の値を処理しようとしているのか次第ですが、大きければ相当時間がかかると思われます。

    for x in pressure:
        if x not in pressure_uniq:
            pressure_uniq.append(x)

早いソートアルゴリズムであるクイックソートの計算量のオーダーは N・Log(N)ですから、pressureをソートした後に、先頭から順に同じ値が並んでいる(重複した値)部分を取り除く(計算量のオーダーはN)ようにすると高速化できるかと思われます。

投稿

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

  • 2019/02/05 16:51

    すいません,ほぼ初心者なので
    あまり理解ができないです...

    クイックソートというモヂュールがあるのですか?

    キャンセル

  • 2019/02/05 17:02

    https://webbibouroku.com/Blog/Article/py-quicksort にコード例があります。とっても有名なアルゴリズムなので、多くのプログラムの教科書に出ています。

    キャンセル

  • 2019/02/05 17:18

    9000*252行の一列のデータだと、データ数は230万(2.3M)ほど。二乗すると計算量は5.3兆(5.3T)。8コア、3GHzクロックのCPUで毎秒10億回(1G)の計算ができるなら、データの読み込みを除いて、5000秒(1時間半)ぐらいかなぁ。スワップが起きないように十分なメモリを積んでいるマシンなら。

    キャンセル

0

どこの処理が遅いのか調べてみてください。処理によって最適化する方法が変わってきますので。

print も多いと負荷になるし。

y_waiwai さんと同じで、私もファイル読み込みかなぁ。それだけのデータをリレーショナル・データベースにいれるだけでも時間がかかりそう。

というか、「とてつもなく遅い」って、正確に何分でしょうか?

ひとによって時間の感覚は違います。これ、10分でおわるなら、そんなもんではないでしょうか?

投稿

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

  • 2019/02/05 16:59

    たぶん,終わるのに2時間程度かかるかとおもいます.
    30分でi=80程度しかいってないです.

    どこに時間がかかるか調べてみます.

    キャンセル

  • 2019/02/05 17:10

    そうやらユニークの部分でした.
    ファイルの読み込みは全て1秒以内でした.

    ユニークに時間がどんどん増えて行ってます.
    どんどんappendされているからだとは思いますが...

    キャンセル

0

lst = []
for i in range(252):
    print(i)
    pressure1 = pd.read_csv('pressure1/probedata_dome_prs_p'+str(i+1), delim_whitespace=True, comment='#',names=['A', 'B', 'C'])
    pressure2 = pd.read_csv('pressure2/probedata_dome_prs_p'+str(i+1), delim_whitespace=True, comment='#',names=['A', 'B', 'C'])
    pre1 = pressure1['C']
    pre2 = pressure2['C']
    lst.append(pre1)
    lst.append(pre2)

s = set()
for pre in lst:
    for x in pre:
        if x not in s:
            s.add(x)
            pressure_uniq.append(x)

array_pressure_uniq = np.array(pressure_uniq)
reshape_pressure_uniq = array_pressure_uniq.reshape(252,9000)
np.savetxt('reshape_pressure.csv',reshape,delimiter=',')
解説

listのinは線形探索なので時間がかかります。setにして高速化を図ります。

コードを単純化するために重複除去はループ外に追い出しています。

投稿

編集

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

0

ダブりを消すのはnp.uniqueに任せた方がよいと思います。
また、あらかじめ読み込むデータ個数が分かっている場合は、その個数分の入れ物を用意しておいたほうが速くなります。
以下テストコードでは一瞬で処理できました。

import pandas as pd
import numpy as np

L,M = 4500,252
a = np.empty((L*2*M)) # 空の入れ物を用意。9000*252

for i in range(M):
    print(i)

    # ダミーデータ
    df1 = pd.DataFrame({'C':np.random.rand(L)})
    df2 = pd.DataFrame({'C':np.random.rand(L)})

    # とにかく読み込む
    a[i*L    :(i+1)*L] = df1['C'].values
    a[(i+1)*L:(i+2)*L] = df2['C'].values

print(a.shape) # (2268000,)
# 並びを維持したままダブりを消す
# https://stackoverflow.com/questions/15637336/numpy-unique-with-order-preserved
_, idx = np.unique(a, return_index=True)
a = a[np.sort(idx)]
print(a.shape) # (1138501,)
# a = a.reshape(M,L*2) # ダブりを消すとこのカタチにならないのでは?


ちなみにですが、ダブりを消すとデータ個数が変わるのでreshape(252,9000)できないのでは?
それともダブり消したあとの個数が固定(252*9000)ということでしょうか?

投稿

編集

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

  • 2019/02/05 17:44

    np.uniqueはソート後の順序で結果を返すので(ソートしてgroupby的な実装)、コードの意味が変わります。

    キャンセル

  • 2019/02/05 17:48

    ご指摘ありがとうございます。
    順序は維持しないといけないのか…

    キャンセル

0

まずはProfileで実際に何が遅いのか見える化するのが鉄則ですよ。
https://docs.python.jp/3/library/profile.html?highlight=profile

投稿

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

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

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

関連した質問

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