私は非常に大きなCSVファイル〜800,000行を持っています。私はスクリプトをスピードアップするためにこのファイルをparellelで処理しようとします。ルビーを使用してCSVファイルを並列処理する
Rubyを使用してファイルをn個の小さな断片に分割するにはどうすればよいですか?
私は非常に大きなCSVファイル〜800,000行を持っています。私はスクリプトをスピードアップするためにこのファイルをparellelで処理しようとします。ルビーを使用してCSVファイルを並列処理する
Rubyを使用してファイルをn個の小さな断片に分割するにはどうすればよいですか?
CSVファイルをチャンクに分割するのは順番ですが、各チャンクはCSVヘッダーの最初の行を保持する必要があります。
UNIX 'split'はそれをカットしません!
最初の行を読み込んで変数に格納し、次のN行を新しい部分CSVファイルに配布する小さなRubyスクリプトを作成する必要がありますが、最初にCSVヘッダー行をコピーします。
ヘッダーと行の塊で各ファイルを作成したら、Resqueワーカーによる並列処理のためにResqueを使用してこれらのファイルを登録できます。
私はこのファイルを多数の小さなファイルに分割するためにlinux splitコマンドを使用します。次に、これらの小さな部品を処理します。
ボトルネックはディスクです。ファイルを別々のディスクに保存しない限り、小さなファイルに分割することはできません。 – pguardiario
が該当する可能性がありますが、ディスクへのアクセスを回避する方法について説明します。複数のスレッドであっても、スレッドが何らかの操作を実行するたびに、各スレッドまたはファイルハンドル位置のファイルハンドルを移動する必要があります。したがって、別々のファイルと別のプロセス(またはスレッド)を使用すると、I/Oに関連するスレッドの中断による待ち時間を最小限に抑えることができます。私が間違っている? – tartar
分割プロセス行ですが、CSVは引用されたフィールドに改行を埋め込むことができるため、改行のみの分割は一般的な場合は控えめです。 – dbenhur
CSVファイルについては、これを行うことができます。array(メモリ)またはファイルに保存する行(または分割さライン)により、
open("your_file.csv").each_line do |line|
# do your stuff here like split lines
line.split(",")
# or store them in an array
some_array << line
# or write them back to a file
some_file_handler << line
end
は、あなたが小さな部分に大きなファイルを分割することができます。その後、スレッドを使用して各ピースを処理することができます。
threads = []
1.upto(5) { |i| threads << Thread.new { do your stuff with file[i] } }
threads.each(&:join)
スレッドを安全に保つ責任があります。
希望すると便利です。
更新:
pguardiarioのアドバイスによると、私たちはスタンドのライブラリーからではなく直接ファイルを開くのCSVファイルを使用することができます。
これはcsvファイルを処理するための間違った方法です。代わりにCSVライブラリを使用してください。 – pguardiario
ええ、私たちはcsv libを使うべきです。しかし、恩恵ですか? – Tomato
ほとんどの場合、引用符とヘッダーが必要ですが、詳細はドキュメントをご覧ください。あなたが正しい方法で何かをしたときに得られる良い気持ちも:) – pguardiario
処理の高価な部分は何ですか?それは主にCSV自体の解析ですか、それとも後続の計算ですか?計算は実際に並列化に適しているのですか、それとも以前の入力に依存していますか?レコードセパレータを簡単に識別できますか(たとえば、各レコードが「\ n」で終わっているか、フィールドに「\ n」埋め込まれている可能性がありますか)? – dbenhur