- ベストアンサー
pythonでの実績データの処理プログラムの速度を早くしたいんですが...
pythonで実績データの解析プログラムを作ったんですが処理が遅くてなかなか使い勝手が悪いんです。処理を早くしようと書き直したいんですが、頭が固まっちゃってうまい案が出てこないんです。 csvファイル形式で一行目がカラム名、10列あって2列目に日付[カラム名でymd]で、形式は2007-05-01という感じです。10列目に人数[カラム名amt]があり、来店人数を日別ごとの小計で出したいんです。 日付 小計 日付 小計 : こんな感じです。 一応プログラムはこんな感じです。 #!/usr/bin/env python import time t1 = time.time() def readcsv(filename): L = [line[:-1] for line in file(filename).readlines()] return map((lambda s: s.split(',')), L) csvlist = readcsv(./csv.csv') totalamt = {} for line in csvlist[1:]: buydict = dict(zip(csvlist[0], line)) if 'ymd' in buydict.keys(): if not buydict['ymd'] in totalamt: totalamt[buydict['ymd']] = 0 totalamt[buydict['ymd']] += int(buydict['amt']) for k in sorted(totalamt.keys()): print '%s , %d' % (k, totalamt[k]) t2 = time.time() print t2 - t1, 'sec' 結果はちゃんと出るんですが、遅いんです。 処理速度を早くしたいんです。誰かご教授御願いします。
- みんなの回答 (2)
- 専門家の回答
質問者が選んだベストアンサー
http://okwave.jp/qa5421190.html と同じ内容で、違うIDなのはなぜなんでしょうか? 遅いから早くしたいということですが、どのくらいのデータを食わせて 現状どのくらいの時間がかかり、それをどのくらい改良したいのでしょうか? 以前 C/C++ カテゴリにあったものから判断して import random def make_record(y, m, d): __return ",".join([str(x) for x in ((random.randint(20,30)), ____________________________________"%4d-%02d-%02d" % (y, m, d), ____________________________________random.randint(1, 3), ____________________________________random.randint(0, 99), ____________________________________"%03d" % random.randint(11, 18), ____________________________________random.randint(100, 999))]) print "shop,ymd,gend,age,area,amt" for y in range(2008,2009): __for m in range(1, 13): ______for d in range(1, 31): __________for i in range(0, 1000): ______________print make_record(y, m, d) こんなんで適当にデータをでっち上げて試してみましたが #!/usr/bin/env python import sys import time t1 = time.time() def readcsv(filename): __L = [line[:-1] for line in file(filename).readlines()] __return map((lambda s: s.split(',')), L) csvlist = readcsv('./csv.csv') totalamt = {} currentmonth = "" subtotal = 0 t2 = time.time() print >>sys.stderr, t2 - t1, 'sec' #sys.exit() for line in csvlist[1:]: __#1 __#buydict = dict(zip(csvlist[0], line)) __#if 'ymd' in buydict.keys(): __#____if not buydict['ymd'] in totalamt: __#________totalamt[buydict['ymd']] = 0 __#____totalamt[buydict['ymd']] += int(buydict['amt']) __#2 __#if not line[1] in totalamt: __#____totalamt[line[1]] = 0 __#totalamt[line[1]] += int(line[-1]) __#3 __if currentmonth <> line[1]: ______if currentmonth <> "": __________print '%s , %d' % (currentmonth, subtotal) ______currentmonth = line[1] ______subtotal = 0 __subtotal += int(line[-1]) #3 の場合のみ不要 #for k in sorted(totalamt.keys()): #____print '%s , %d' % (k, totalamt[k]) で10メガバイト前後のデータを処理させてみたところ パターン1 1.71900010109 sec 6.17199993134 sec 1.71799993515 sec 6.17199993134 sec 1.71900010109 sec 6.18800020218 sec パターン2 1.7349998951 sec 2.82799983025 sec 1.71899986267 sec 2.79699993134 sec 1.70300006866 sec 2.79699993134 sec パターン3 1.71899986267 sec 2.64100003242 sec 1.70299983025 sec 2.625 sec 1.70300006866 sec 2.625 sec こんな感じでした。 いずれにしても情報が少なすぎですね。
その他の回答 (1)
- Tacosan
- ベストアンサー率23% (3656/15482)
python は使っていないけど, このプログラムで時間がかかりそうなのは ・ファイルを読み込むときに全体を一度に読み込んでいる ・連想配列 (辞書) を使っている ところかな. 前者については「1行ずつ読み込んでそのたびに処理をする」, 後者については (必要なフィールドがどこかをあらかじめ調べておいて) 「配列要素の参照に置き換える」と速くなるかもしれません. いずれにしても, 現在のプログラムで「どこで時間がかかっているのか」をまず把握する必要があると思います. その上で「どこに手を加えるか」を考えないと, 労力のわりに効果が出ないことはよくあります.
補足
配列要素の参照ですか? うーん、勉強不足なのでいまいち理解できないんですが。もう少し調べてみます。pythonに触れ始めて1週間なもので、なかなか理解が追いつかなくて。 今回のプログラムでは、日付別に足さなきゃいけなかったので、日付をキーとした辞書を使って足す、という方法しか日付分けのしかたを考え付かなかったんです。 あとは、1行づつ読み込んで処理する方法も考えてみます。