3

Pythonで作業するのはこれで2日目です。しばらくの間C++で作業しましたが、Pythonを試すことにしました。私のプログラムは期待通りに動作します。ただし、globループを使用せずに一度に1つのファイルを処理すると、ファイルごとに約30分かかります。グロブを含めると、ループは8つのファイルを処理するのに約12時間かかります。

私の質問はこれです、私のプログラムに間違いなくそれを遅くしているものはありますか?それを速くするために私がすべきことはありますか?

大きなファイルのフォルダがあります。例えば

file1.txt(6gb)file2.txt(5.5gb)file3.txt(6gb)

それが役立つ場合、データの各行は、残りの文字がどのようにフォーマットされているかを示す文字で始まります。そのため、すべてのifelifステートメントがあります。データの行は次のようになります:T35201 M352 RZNGA AC

各ファイルを読み取り、分割を使用して解析を実行してから、ファイルを保存しようとしています。

コンピューターには32GBのRAMがあるので、私の方法は、各ファイルをRAMに読み込んでから、ファイルをループして保存し、次のファイルのRAMをクリアすることです。

私が使用しているメソッドを確認できるように、ファイルを含めました。約10種類のelifコマンドを使用するifelifステートメントを使用します。私は辞書を試しましたが、命を救うためにそれを理解することができませんでした。

どんな答えも役に立ちます。

import csv
import glob

for filename in glob.glob("/media/3tb/5may/*.txt"):
    f = open(filename,'r')
    c = csv.writer(open(filename + '.csv','wb'))

    second=0
    mill=0
    for line in f.readlines():
       #print line
        event=0
        ticker=0
        marketCategory=0
        variable = line[0:1]    

        if variable is 'T':
           second = line[1:6]
           mill=0
        else: 
           second = second 

        if variable is 'R':
           ticker = line[1:7]   
           marketCategory = line[7:8]
        elif variable is ...
        elif variable is ...
        elif ...
        elif ...
        elif ...
        elif ...
        elif        

        if variable (!= 'T') and (!= 'M')
            c.writerow([second,mill,event ....]) 
   f.close()

UPDATE 各elifステートメントはほぼ同じです。変更されるのは、行を分割する方法だけです。ここに2つのelifステートメントがあります(合計13あり、分割方法を除いてほとんどすべて同じです)。

  elif variable is 'C':
     order = line[1:10]
     Shares = line[10:16]
     match = line[16:25]
     printable = line[25:26]
     price = line[26:36]
   elif variable is 'P':
     ticker = line[17:23]
     order = line[1:10]
     buy = line[10:11]
     shares = line[11:17]
     price = line[23:33]
     match = line[33:42]

UPDATE22for file in fつの異なる時間 を使用してコードを実行しました。初めて1つのファイルを実行せず for filename in glob.glob("/media/3tb/file.txt"):に実行したとき、1つのファイルのファイルパスを手動でコーディングするのに約30分かかりました。

でもう一度実行 for filename in glob.glob("/media/3tb/*file.txt")ましたが、フォルダー内の1つのファイルだけで1時間かかりました。グロブコードはそれだけの時間を追加しますか?

4

4 に答える 4

9

ここ:

for line in f.readlines():

あなたはこれをするべきです:

for line in f:

前者はファイル全体を行のリストに読み込み、そのリストを繰り返し処理します。後者はそれを段階的に行います。これにより、プログラムによって割り当てられ、後で解放されるメモリの合計が大幅に削減されます。

于 2013-02-22T14:06:00.523 に答える
2

「これのどの部分が全体を遅くしているのか」と尋ねるときはいつでも。答えは「プロファイルする」です。これを行う方法については、 PythonProfilersのPythonのドキュメントに優れた説明があります。また、John Zwinckが指摘しているように、一度に大量のメモリをロードしているため、一度に1行だけロードする必要があります(ファイルオブジェクトはPythonでは「反復可能」です)。

個人的には、Perlが「ディスパッチテーブル」と呼んでいる巨大なif..elif...elif怪物よりも好きです。 このWebページでは、Pythonの方法について説明しています。これは関数のキーの辞書であり、すべての場合に機能するわけではありませんが、単純な場合if x==2:...elif x==3...(つまり、1つの変数の値をオンにする場合)はうまく機能します。

于 2013-02-22T14:18:27.127 に答える
1

反復可能(yieldを使用)を使用して、一度に1行だけではなく、一度にファイル全体ではなく、より多くの行をメモリに「バッファリング」します。

def readManyLines(fObj,num=1000):
  lines = fObj.readlines(num)
  for line in lines:
    yield line

f = open(filename,'r')
for line in readManyLines(f):
  process(line)
于 2013-02-22T18:17:31.057 に答える
0

これがまったく役立つかどうかはわかりませんが、問題であることを除外するために、glob.globの代わりにこれを使用してみてください。私はWindowsを使用しているので、これがUNIXで機能することを100%確信することはできませんが、なぜ機能しないのかわかりません。

import re
import os
import csv

def find_text_files(root):
    """Find .txt files under a given directory"""
    foundFiles = []
    for dirpath, dirnames, filenames in os.walk(root):
        for file in filenames:
            txt = re.compile(r'txt$',re.I,).search(file)
            if txt:
                foundFiles.append(os.path.join(dirpath,file))
    return foundFiles

txtfiles = find_text_files('d:\files') #replace the path with yours

for filename in txtfiles:
    f = open(filename,'r')
    c = csv.writer(open(filename + '.csv','wb'))
于 2013-02-22T18:36:44.030 に答える