【解析Tips】[Linux]コマンドラインで済ませよう(前処理編)
■ 大抵のことはコマンドラインでできる
ビッグデータの分析はまずCSVをDBに入れる所から始まりますが、素直にDBに入るデータなら苦労しません。素直に入らないデータだからこそ、データの前処理が必要になります。
この「コマンドラインで済ませよう」シリーズでは、数GB~数十GBぐらいのデータでも対応できる、コマンドラインでできる前処理Tipsを紹介していきます。前回記事は↓をご覧ください。sortとuniqが最強だという話をしました。
■ grep・sed・awk
前回はsortとuniqを使えば大体の異常値探しや変なファイルのカウントができますよ、という話をしたので、今回はその次のステップとして、異常値の置換やフォーマット整形などを行いたいと思います。主役はgrep・sed・awkですね。特にawkはイケメンなので、大体の事はawkでできます。ただ書き方に癖があるので、awk特集は次回以降に回して、ここではgrepやsedメインで紹介します。
(1)ファイルの結合
なんかファイルが店舗に分かれたり年月日で分かれたりして、膨大なファイル数になることがあると思います。そんなファイルをスッキリ1ファイルにまとめたいときは以下のコマンドが便利です。
#全てのCSVファイルの中身を表示して、順番を並び替えて、重複を除いてall.csvへ
cat *.csv | sort -n | uniq > all.csv
ここでもsort&uniqが活躍していますね。だいたい前回のような異常値を抜いた後のcsvは大体フォーマットが揃っているので、ヘッダーが1行あって、あとは月別なり店舗別に数字が並んでいることが多いと思います。
でも分析する時に月別に違うファイルは読みに行きたくないので、上記コマンドで1つにまとめてしまいましょう。ポイントはsort -nです。普通にcatすると結合した後のファイルの途中にヘッダが紛れてしまうのですが、これで各ファイルのヘッダが全部先頭行に統合されます。そのあとのuniqで各ファイルのヘッダが重複行とみなされて結果的に1行にまとめられるので、すっきり1ファイルにすることができます。
※ただし、データの中に全く同じ行があり、重複削除せずに2行としてカウントしたい場合は、最後のuniqを外していただき、その後に手動でヘッダを外してください。
ヘッダは要らないよ、という場合は以下のようにawk君がイケメンです。
#各ファイルの2行目以降を1ファイルにまとめる
awk 'FNR>=2' *.csv > all.csv
(2)異常値をとり除く
だいたいは複数ファイルをまとめて1ファイルにした方が、その後の処理がやりやすいと思います。異常値が入っている行をスキップしたいとか、異常値を置換したいとか、そんな作業がしたいときもあると思います。
例えば異常値が-9999で入っている場合、その行を除く時などはgrepの-vオプションが活躍します。
# -9999が入っている行を外す
grep -v "\-9999" all.csv > all_without_nan.csv
ただこれだと行のどこかに-9999がある行が全部外されてしまうので、特定の列の-9999を対象にしたい場合は、またイケメンawk君の力を借りましょう。
# 4列目が-9999となっている行だけ外す
awk -F"," '$4!=-9999' all.csv > all_without_nan_l4.csv
(3)異常値を置換する
異常値は取り除いてしまうとレコード数が変わるため、異常値として残したい場合もあると思います。そんな時は置換ですね。sedで一気に済ませましょう。
#-9999をNaNに置換
sed "s/-9999/NaN/g" all.csv > all_rep_nan.csv
sedは異常値のみならず区切り文字の置換にも使えます。csvの皮を被りながら中身はタブ区切りやスペース区切りのデータもあると思うので、そういうファイルに遭遇した場合に使いましょう。
#csvをtsvに変換
sed s"/,/\t/g" all.csv > all.tsv
(4)特定条件の行のみを抽出する
分析にかけるにしても、「全ユーザーのデータもらったけど今回は40代のみが分析対象なんだけど」とか、「東京都のみを対象にしたいんだけど」のようなケースが出てくると思います。そうすると全部をRDBに入れてしまうと処理が重くなったりするので、はじめにcsvで抽出してから入れる、というパターンも考えられると思います。
# 東京都が入っている行のみを抽出
grep 東京都 all.csv > tokyo.csv
いやいや首都圏が対象なんだけど、という場合は、以下のようなファイルを用意して、grepの-fオプションを使いましょう。店舗コードでもユーザーIDでも何でも使えます。
#shutoken.txt
東京都
千葉県
神奈川県
埼玉県
# 首都圏が含まれる行のみ抽出する
grep -f shutoken.txt all.csv > ext_shutoken.csv
※そしてgrepは便利なことに圧縮ファイルにも適用できるので、重たいcsvの場合は一度zip圧縮してからzgrepをかけるという手も有効です。
#all.csvを圧縮(all.csv.gz)
gzip all.csv
# 首都圏が含まれる行のみ抽出する
zgrep -f shutoken.txt all.csv.gz > ext_shutoken.csv
異常値も除去したり置換したりしたし、必要な行だけ抽出もしたし、これでだいぶ分析しやすくなりましたね!
ではまた!(^-^)
この記事が気に入ったらサポートをしてみませんか?