0

ここに私の既存のコードがあります:

////////////// = []
for line in datafile:
    splitline = line.split()
    for item in splitline:
        if not item.endswith("JAX"):
            if item.startswith("STF") or item.startswith("BRACKER"):
                //////////.append( item )


for line in //////////
    print /////////////
   /////////// +=1
    for t in//////
        if t in line[:line.find(',')]:
            line = line.strip().split(',')
           ///////////////write(','.join(line[:3]) + '\n') 
            break

/////////////.close()
/////////////close()
///////////.close()

さらなる最適化を行いたいと考えています。ファイルは本当に大きいです。大きなファイルを検索するのにかかる時間を短縮するために、一致して小さなファイルに書き込まれた後に一致した行を削除したいと思います。これについてどうすればよいかについての提案はありますか?

4

2 に答える 2

1

テキスト ファイルの行を削除することはできません。ギャップを埋めるには、削除された行の後のすべてのデータを移動する必要があり、非常に非効率的です。

これを行う 1 つの方法は、保持したいすべての行を含む一時ファイルを bigfile.txt に書き込むことです。処理が終了したら、bigfile.txt を削除し、一時ファイルの名前を変更して置き換えます。

または、bigfile.txt がメモリに収まるほど小さい場合は、ファイル全体をリストに読み込み、リストから行を削除してから、リストをディスクに書き戻すことができます。

また、あなたのコードから、bigfile.txt はある種の CSV ファイルであると推測します。その場合は、データベース ファイルに変換し、SQL を使用してクエリを実行する方がよい場合があります。Python には SQLite モジュールが組み込まれており、他のほとんどのデータベース用のサードパーティ ライブラリがあります。

于 2010-08-05T19:32:46.990 に答える
0

コメントで言ったように、「bigfile」のサイズがカウントの増加速度を遅くしているようには見えません。そのようなファイルを繰り返し処理する場合、Python は一度に 1 行ずつ順番に読み取るだけです。

この時点で実行できる最適化は、matchedLines の大きさと、matchedLines 文字列と探しているテキストとの関係によって異なります。

MatchedLines が大きい場合は、「検索」を 1 回だけ実行することで時間を節約できます。

for line in completedataset:
   text = line[:line.find(',')] 
   for t in matchedLines:
        if t in text:
            line = line.strip().split(',')
            smallerdataset.write(','.join(line[:3]) + '\n') 
            break

私のテストでは、「検索」に約 300 ナノ秒かかりました。

部分文字列の一致ではなく、完全一致を探している場合は、セットを使用して高速化できます。

matchedLines = set(matchedLines)
for line in completedataset:
    target = line[:line.find(',')]
    ## One lookup and you're done!
    if target in matchedLines:
        line = line.strip().split(',')
        smallerdataset.write(','.join(line[:3]) + '\n') 

一致しないターゲット テキストが一致するものとは完全に異なるように見える傾向がある場合 (たとえば、ほとんどのターゲットがランダムな文字列で、matchedLines が一連の名前である)、かつ、matchedLines がすべて特定の長さを超えている場合は、部分文字列をチェックして、本当に賢くなるようにしてください。すべてのmatchedLinesの長さが少なくとも5文字であると仮定します...

def subkeys(s):
    ## e.g. if len(s) is 7, return s[0:5], s[1:6], s[2:7].
    return [s[i:i+5] for i in range(len(s) + 1 - 5)]

existing_subkeys = set()
for line in matchedLines:
    existing_subkeys.update(subkeys(line))

for line in completedataset:
    target = line[:line.find(',')]
    might_match = False
    for subkey in subkeys(target):
        if subkey in existing_subkeys:
            might_match = True
            break
    if might_match:
        # Then we have to do the old slow way.
        for matchedLine in matchedLines:
            if matchedLine in target:
                # Do the split and write and so on.

しかし、そのようなことをしようとして自分の裏をかくのは本当に簡単です。それは、データがどのように見えるかによって異なります。

于 2010-08-06T17:30:34.143 に答える