2つの大きなtxtファイル(両方とも約100GB、10億行、いくつかの列)をスキャンし、特定の列を取り出す(新しいファイルに書き込む)必要があります。ファイルは次のようになります
ID*DATE*provider
1111*201101*1234
1234*201402*5678
3214*201003*9012
...
私のPythonスクリプトは
N100 = 10000000 ## 1% of 1 billion rows
with open("myFile.txt") as f:
with open("myFile_c2.txt", "a") as f2:
perc = 0
for ind, line in enumerate(f): ## <== MemoryError
c0, c1, c2 = line.split("*")
f2.write(c2+"\n")
if ind%N100 == 0:
print(perc, "%")
perc+=1
これで、上記のスクリプトは1つのファイルに対しては正常に実行されますが、62%で別のファイルに対してスタックします。エラーメッセージにはMemoryError
、が表示されfor ind, line in enumerate(f):
ます。異なるRAMを搭載した異なるサーバーで数回試しましたが、エラーは同じで、すべて62%です。RAMを監視するために何時間も待ちましたが、62%のときに28GB(合計= 32GB)に爆発しました。したがって、そのファイルには、どういうわけか長すぎる(おそらく\n
?で終わっていない)行があり、RAMに読み取ろうとしたときにPythonがスタックしたと思います。
だから私の質問は、データプロバイダーに行く前に、エラーラインを検出し、それを1つの巨大なラインとして読み取って回避/スキップするにはどうすればよいですか?提案に感謝します!
編集:
'エラー行'で始まるファイルは、\n
。ではなく別の行区切り文字ですべて混乱している可能性があります。その場合、行の区切りを検出して、必要な列を破棄するのではなく、抽出を続けることができますか?ありがとう!
この(テストされていない)コードは、問題を解決する可能性があります。最大メモリ消費量を削減するために、入力を読み取りあたり1,000,000バイトに制限します。
このコードは、各行から最初の100万文字を返すことに注意してください。長い列に対処する方法には他の可能性があります。
#UNTESTED
def read_start_of_line(fp):
n = int(1e6)
tmp = result = fp.readline(n)
while tmp and tmp[-1] != '\n':
tmp = fp.readline(n)
return result
N100 = 10000000 ## 1% of 1 billion rows
with open("myFile.txt") as f:
with open("myFile_c2.txt", "a") as f2:
perc = 0
for ind, line in enumerate(iter(lambda: read_start_of_line(f), '')):
c0, c1, c2 = line.split("*")
f2.write(c2+"\n")
if ind%N100 == 0:
print(perc, "%")
perc+=1
この記事はインターネットから収集されたものであり、転載の際にはソースを示してください。
侵害の場合は、連絡してください[email protected]
コメントを追加