#はじめに
業務でメモリに乗らない数百GB以上のデータを扱う機会がありましたが、
そこで、Pandas等がうまく使えず困ったことが発生したました。
その内容を踏まえて以下の内容についてまとめていきます。
同じような問題にぶつかった方に、少しでも役立てばと思います!
①Linuxでのファイル分割(この記事)
②Daskでの分散処理
③大規模データでのダミー変数化
##データが大きいと何が困るのか
処理が重くなったり、遅くなったりするのはなんとなくイメージつくかと思います。
処理スピードに関してはマシンパワーやCPUコア数に依存すると思いますので、唇を噛んで受け入れるしかないこともありますがただ遅くなるだけでなく、できないこともでてきます。
例えばcsvをpd.read_csv()
でDataFrameに読み込むと、CSV上のデータが
全てDataFrameに入りますが、これはメモリ領域を使っています。
私の会社のマシンは多くてもメモリ16GBのため、仮にcsvが100GBあった場合、領域が足りずpd.read_csv()
でエラーを吐き、データが読み込めません。
こうなってしまった場合の対処方法としては、ファイルを分割するかデータを分割するしか無いかと思います。
###ファイルを分割するとは...
100GBのcsvを1GBずつ100個のファイルに分けるということです。
そして、本来100GB一気に流したかった処理を1ファイルずつ100回実行することになります。
これだと、手間はかかりますがメモリを一度に大量消費しないで処理できます。
###データを分割するとは...
100GBのcsvを1GBずつ読み込んで行くということです。
先の例で言うと、csv全体でなく1GB読み込んでDataFrameに入れ、処理が終わったらまた次の1GBをDataFrameに読み込んで同じ処理をする、という流れをイメージしてください。
どこで分散(分割)するかが違うだけで、やっていることは同じですよね!
このページではタイトルの通り、Linuxでのファイル分割について説明したいと思います。
Linuxでのファイル分割
そもそも、
「このcsvを3つに分割してください!」
と言われたらどうしますか?
私はWindowsで仕事していますが、真っ先にエクセルで開いて行数を確認し、行数を3分割して3つのエクセルシートにコピペすることを想像します。
しかし、ファイルを開くというのもまたメモリを使うので、大規模データをダブルクリックして開こうとした時点でメモリを食いつぶしてPCが固まってしまいます。もちろん、他のテキストエディタ等でやっても同じです。
「じゃあファイルの中見れないじゃん!!!!!」
と思いますが実はその通りです。だから面倒臭いのです...
ファイルの中身を確認せずに綺麗に分割することはヒューマンにはできないので、PCにお願いするしかないのです。
(Windowsでそのままやりたいのに)なぜLinux?
Windowsにはファイル操作するためのコマンドがそれほど充実していないからだと思います。
ググれば、「Windows環境でファイル分割用のbat作ってみた」的な記事もでてきますが、どれも1つや2つのコマンドで完結するものではありません。
Linuxであれば専用の便利なコマンドがいくつかありますのでわかりやすいですし、MacOSで開発されている方ならそのままLinuxコマンドが使えるかと思います!(羨ましいぜ!)
私はWindowsで仕事していますので、VitualBoxにUbuntuをインストールしてその中にファイルを渡してファイルを分割してもらっています。
字面を見ると「うわぁ、めんどくせえ...」と思いますが、個人的にはファイルの分割自体、前処理の前処理で使う程度ですし、使うコマンドもシェルスクリプトにしておけば打ち直す必要もなく応用効くので意外とそうでもないです。
(セッティングするのがそもそもめんどくさいですけどね...仮想環境とホスト側のフォルダを共有させるのにも最初は詰まって投げかけました。笑)
## ファイル分割処理用のコマンド紹介まとめ
less
詳しい文法はこちら
先に「大規模ファイルは開けない」と書きましたが、それでも中身の状態を確認しないとどうにもこうにもなりません。
lessコマンドはページ単位でファイルを表示してくれるコマンドです。
ページ分しか表示しないので、大きなデータでも気軽に確認することができます。
(個人的にはcatの安全版だと思って使っています)
私はファイル分割・連結後に結果確認としてファイルの状態を見たい時などによく使っています!
head
詳しい文法はこちら
名前の通り、ファイルの「頭」を表示することができ、デフォルトでは最初の10行だけ表示します。
lessのファイル保存オプションをいつも忘れるのでファイルにリダイレクトしたい時に
私は$head -n 1 your_filename > columns.csv
でカラム名だけをゲットしたい時等によく使っています!
split
詳しい文法はこちら
ファイルを分割するコマンドです。本日の主役、お世話になっております。
-l
オプションで指定行数ごとでの分割、-b
オプションで指定サイズごとでの分割、-n
オプションで指定個数での分割ができます。
cut
詳しい文法はこちら
csvファイルを縦に分割したい時はsplitではなくcutコマンドを使います。
特定のカラムのデータだけズボっと抜き取りたい場合はこちらをお使いください。
grep
詳しい文法はこちら
ファイルを分割したあとのデータ管理に使います。
特に、ファイルを何十個にも分割したあとに特定のデータを探すのは
grepなくしてはもう無理です。
##最後に
今回はファイル分割についてまとめましたが、ライブラリを使ってPython上でデータを分割する方法については次の記事をご覧になてください!!
【初めての大規模データ②】Daskでの並列分散処理