3

最初の投稿、あなたが望むように批判的になりなさい...

私の問題:1億4000万行の非常に大きなファイル(ファイル1)と300万行のわずかに小さいファイル(ファイル2)があります。ファイル2と一致するファイル1の行を削除したいと思います。直感的には、これはそれほど長くはかからない単純な検索と削除の問題のように見えました。私のコードは、24Gbプロセッサで実行するのに最大4日かかります。これをいくつかのファイルで実行したいので、時間の改善を望んでいます。ヘルプやコメントをいただければ幸いです。

サンプルファイル1:

reftig_0 43 0 1.0
reftig_0 44 1 1.0
reftig_0 45 0 1.0
reftig_0 46 1 1.0
reftig_0 47 0 5.0

サンプルファイル2:

reftig_0 43
reftig_0 44
reftig_0 45

コード:

data = open('file_1', 'r')
data_2 = open('file_2', 'r')
new_file = open('new_file_1', 'w')

d2= {}
for line in data_2:
    line= line.rstrip()
    fields = line.split(' ')
    key = (fields[0], fields[1])
    d2[key]=1

#print d2.keys()
#print d2['reftig_1']
tocheck=d2.keys()
tocheck.sort()
#print tocheck

for sline in data:
    sline = sline.rstrip()
    fields = sline.split(' ')
    nkey = (fields[0],fields[1])
    #print nkey
    if nkey in tocheck:
        pass
    else:
        new_file.write(sline + '\n')
        #print sline
4

3 に答える 3

4

これは、以下を使用してより適切にアプローチできますgrep

grep -Fvf file2 file1
于 2012-10-21T01:35:39.473 に答える
4

行が。に対してif nkey in tocheckチェックしているため、スクリプトは低速です。これは線形検索であるため(ソートされていても)、非常に低速です。nkeylisttocheck

set代わりに使用してください:

def getkey(line):
    line = line.rstrip()
    fields = line.split(' ')
    return (fields[0], fields[1])

tocheck = {getkey(line) for line in data_2}

for line in data:
    if getkey(line) not in tocheck:
        new_file.write(line)

これをunutbuの書き込みバッチ処理と組み合わせると、スクリプトはかなり高速に実行されます。

于 2012-10-21T01:43:42.507 に答える
3

1行に1回の短い文字列の書き込みnew_fileは遅いです。new_fileリストにコンテンツを追加し、リストの長さが1000行の場合にのみ書き込むことで、書き込み回数を減らします。

N = 1000
with open('/tmp/out', 'w') as f:
    result = []
    for x in range(10**7):
        result.append('Hi\n')
        if len(result) >= N:
            f.write(''.join(result))
            result = []

time test.pyこれは、次のさまざまな値に対して実行した結果ですN

|      N | time (sec) |
|      1 |      5.879 |
|     10 |      2.781 |
|    100 |      2.417 |
|   1000 |      2.325 |
|  10000 |      2.299 |
| 100000 |      2.309 |
于 2012-10-21T01:40:01.363 に答える