巨大な CSV ファイルの読み取り: メモリと速度の最適化
数百万の行と数百の列を含む大規模な CSV ファイルを処理しようとする場合、従来のイテレータを使用するアプローチでは、メモリ関連の問題が発生する可能性があります。この記事では、Python 2.7 で大規模な CSV データを処理するための最適化された手法について説明します。
メモリの最適化:
メモリの問題の核心は、メモリ内リストの構築にあります。大規模なデータセットを保存します。この問題を軽減するために、Python は関数をジェネレーター関数に変換する yield キーワードを提供します。これらの関数は、各 yield ステートメントの後で実行を一時停止し、データが発生するたびに増分処理できるようにします。
ジェネレーター関数を使用すると、データを行ごとに処理できるため、ファイル全体をメモリに保存する必要がなくなります。次のコードは、このアプローチを示しています。
import csv def getstuff(filename, criterion): with open(filename, "rb") as csvfile: datareader = csv.reader(csvfile) yield next(datareader) # yield header row count = 0 for row in datareader: if row[3] == criterion: yield row count += 1 elif count: # stop processing when a consecutive series of non-matching rows is encountered return
速度の強化:
さらに、Python のdropwhile 関数と takewhile 関数を活用して、処理速度をさらに向上させることができます。これらの関数はデータを効率的にフィルター処理できるため、目的の行をすばやく見つけることができます。方法は次のとおりです:
from itertools import dropwhile, takewhile def getstuff(filename, criterion): with open(filename, "rb") as csvfile: datareader = csv.reader(csvfile) yield next(datareader) # yield header row yield from takewhile( # yield matching rows lambda r: r[3] == criterion, dropwhile( # skip non-matching rows lambda r: r[3] != criterion, datareader)) return
ループ処理の簡素化:
ジェネレーター関数を組み合わせることで、データセットのループ処理を大幅に簡素化できます。 getstuff と getdata の最適化されたコードは次のとおりです。
def getdata(filename, criteria): for criterion in criteria: for row in getstuff(filename, criterion): yield row
これで、getdata ジェネレーターを直接反復処理できるようになり、行ごとに行のストリームが生成され、貴重なメモリ リソースが解放されます。
目標は、メモリ内のデータ ストレージを最小限に抑えながら、同時に処理効率を最大化することであることに注意してください。これらの最適化手法を適用すると、メモリの障害に遭遇することなく、巨大な CSV ファイルを効果的に処理できます。
以上がメモリの問題を発生させずに、Python 2.7 で巨大な CSV ファイルを効率的に処理するにはどうすればよいでしょうか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。