概要
コマンドライン使ってますか!
シェル芸人の皆さんは日常茶飯事でしょうけど、そこまで極めることなしに手軽に身近なデータ分析に組み込むことのできるツールをご紹介します。
その名も! csvkit!
すぐに特定の変換方法が知りたいせっかちなあなたは下記の目次から飛んでください。
テストデータは公式のものを使って試しています。
内容は公式のチュートリアルから抜粋しているだけなので、もっと機能を知りたい方はぜひ公式ドキュメントを参考にして下さい。
インストール
v1.0.2では警告メッセージが大量に出力される不具合が観測されたため、pipからダウンロードすることのできるv1.0.5を使用するようにしましょう。
$ pip install csvkit
データの変換
データの変換にとっても便利なcsvkit
もちろんRやPython、Excelなんかを開いてデータの加工、変換を行ってもよいですが、コマンドラインでできるととっても楽。
データ分析が捗りますね。
Excel → CSV
Excel のデータをCSVに変換するには、in2csv
の引数にエクセルファイルを渡します。
$ in2csv ne_1033_data.xlsx > data.csv
出力結果
$ head data.csv state,county,fips,nsn,item_name,quantity,ui,acquisition_cost,total_cost,ship_date,federal_supply_category,federal_supply_category_name,federal_supply_class,federal_supply_class_name NE,ADAMS,31001.0,1005-00-589-1271,"RIFLE,7.62 MILLIMETER",1.0,Each,138.0,138.0,2008-07-11,10.0,WEAPONS,1005.0,"Guns, through 30 mm" NE,ADAMS,31001.0,1005-00-589-1271,"RIFLE,7.62 MILLIMETER",1.0,Each,138.0,138.0,2008-07-11,10.0,WEAPONS,1005.0,"Guns, through 30 mm" NE,ADAMS,31001.0,1005-00-589-1271,"RIFLE,7.62 MILLIMETER",1.0,Each,138.0,138.0,2008-07-11,10.0,WEAPONS,1005.0,"Guns, through 30 mm" NE,ADAMS,31001.0,1005-00-589-1271,"RIFLE,7.62 MILLIMETER",1.0,Each,138.0,138.0,2008-07-11,10.0,WEAPONS,1005.0,"Guns, through 30 mm" NE,ADAMS,31001.0,1005-00-589-1271,"RIFLE,7.62 MILLIMETER",1.0,Each,138.0,138.0,2008-07-11,10.0,WEAPONS,1005.0,"Guns, through 30 mm" NE,ADAMS,31001.0,1005-00-589-1271,"RIFLE,7.62 MILLIMETER",1.0,Each,138.0,138.0,2008-07-11,10.0,WEAPONS,1005.0,"Guns, through 30 mm" NE,BUFFALO,31019.0,1005-00-073-9421,"RIFLE,5.56 MILLIMETER",1.0,Each,499.0,499.0,2008-09-24,10.0,WEAPONS,1005.0,"Guns, through 30 mm" NE,BUFFALO,31019.0,1005-00-073-9421,"RIFLE,5.56 MILLIMETER",1.0,Each,499.0,499.0,2008-09-24,10.0,WEAPONS,1005.0,"Guns, through 30 mm" NE,BUFFALO,31019.0,1005-00-073-9421,"RIFLE,5.56 MILLIMETER",1.0,Each,499.0,499.0,2008-09-24,10.0,WEAPONS,1005.0,"Guns, through 30 mm"
CSV → SQL文
csvsql
では、-i
にデータベースの種類を指定すると、
指定したデータベースにおいてCSVと同様のテーブルを作成するためのコマンドを作成してくれます。
$ csvsql -i sqlite data.csv CREATE TABLE data ( state VARCHAR NOT NULL, county VARCHAR NOT NULL, fips FLOAT NOT NULL, nsn VARCHAR NOT NULL, item_name VARCHAR, quantity FLOAT NOT NULL, ui VARCHAR NOT NULL, acquisition_cost FLOAT NOT NULL, total_cost FLOAT NOT NULL, ship_date DATE NOT NULL, federal_supply_category FLOAT NOT NULL, federal_supply_category_name VARCHAR NOT NULL, federal_supply_class FLOAT NOT NULL, federal_supply_class_name VARCHAR NOT NULL );
CSV → RDB
同じく csvsql
で--insert
を使用すると、
CSVファイルを指定してDBにテーブルを追加することができます。
$ csvsql --db sqlite:///leso.db --insert data.csv
RDB → CSV
sql2csv
では、SQLのqueryを使ってRDBからCSVを抽出することができます。
$ sql2csv --db sqlite:///leso.db --query "select * from joined where county='DOUGLAS';" > douglas.csv
JSON → CSV
in2csv
を用いると、標準出力で受け取った値をCSVに変換することができます。
下記はgithubのAPIからJSON形式で取得したissue内容をCSVに変換する例です。
$ curl https://api.github.com/repos/wireservice/csvkit/issues?state=open | in2csv -f json -v
データの閲覧
CSVを見やすくわかりやすく表示するためには、csvlook
が有用です。
下記のような視認性の高い可視化を行ってくれます。
$ csvlook data.csv | head | state | county | fips | nsn | item_name | quantity | ui | acquisition_cost | total_cost | ship_date | federal_supply_category | federal_supply_category_name | federal_supply_class | federal_supply_class_name | | ----- | ---------- | ------ | ---------------- | -------------------------------------------------------------- | -------- | ------- | ---------------- | ---------- | ---------- | ----------------------- | ----------------------------------- | -------------------- | --------------------------------------------------------------- | | NE | ADAMS | 31,001 | 1005-00-589-1271 | RIFLE,7.62 MILLIMETER | 1 | Each | 138.00 | 138.00 | 2008-07-11 | 10 | WEAPONS | 1,005 | Guns, through 30 mm | | NE | ADAMS | 31,001 | 1005-00-589-1271 | RIFLE,7.62 MILLIMETER | 1 | Each | 138.00 | 138.00 | 2008-07-11 | 10 | WEAPONS | 1,005 | Guns, through 30 mm | | NE | ADAMS | 31,001 | 1005-00-589-1271 | RIFLE,7.62 MILLIMETER | 1 | Each | 138.00 | 138.00 | 2008-07-11 | 10 | WEAPONS | 1,005 | Guns, through 30 mm | | NE | ADAMS | 31,001 | 1005-00-589-1271 | RIFLE,7.62 MILLIMETER | 1 | Each | 138.00 | 138.00 | 2008-07-11 | 10 | WEAPONS | 1,005 | Guns, through 30 mm | | NE | ADAMS | 31,001 | 1005-00-589-1271 | RIFLE,7.62 MILLIMETER | 1 | Each | 138.00 | 138.00 | 2008-07-11 | 10 | WEAPONS | 1,005 | Guns, through 30 mm | | NE | ADAMS | 31,001 | 1005-00-589-1271 | RIFLE,7.62 MILLIMETER | 1 | Each | 138.00 | 138.00 | 2008-07-11 | 10 | WEAPONS | 1,005 | Guns, through 30 mm | | NE | BUFFALO | 31,019 | 1005-00-073-9421 | RIFLE,5.56 MILLIMETER | 1 | Each | 499.00 | 499.00 | 2008-09-24 | 10 | WEAPONS | 1,005 | Guns, through 30 mm | | NE | BUFFALO | 31,019 | 1005-00-073-9421 | RIFLE,5.56 MILLIMETER | 1 | Each | 499.00 | 499.00 | 2008-09-24 | 10 | WEAPONS | 1,005 | Guns, through 30 mm
画面サイズによっては折り返しが生じてしまうため、
less -S
にパイプでつなげてあげるのがよいです。
$ csvlook data.csv | less -S
データの抽出
csvcut
コマンドを使用すると、データのトリミングを行うことができます。
-n
で対象のCSVを指定すると、各列のインデックスが表示されます。
$ csvcut -n data.csv
1: state
2: county
3: fips
4: nsn
5: item_name
6: quantity
7: ui
8: acquisition_cost
9: total_cost
10: ship_date
11: federal_supply_category
12: federal_supply_category_name
13: federal_supply_class
14: federal_supply_class_name
-c
でインデックスを指定すると、指定したインデックスのカラムだけを抽出することができます。
$ csvcut -c 2,5,6 data.csv | head county,item_name,quantity ADAMS,"RIFLE,7.62 MILLIMETER",1.0 ADAMS,"RIFLE,7.62 MILLIMETER",1.0 ADAMS,"RIFLE,7.62 MILLIMETER",1.0 ADAMS,"RIFLE,7.62 MILLIMETER",1.0 ADAMS,"RIFLE,7.62 MILLIMETER",1.0 ADAMS,"RIFLE,7.62 MILLIMETER",1.0 BUFFALO,"RIFLE,5.56 MILLIMETER",1.0 BUFFALO,"RIFLE,5.56 MILLIMETER",1.0 BUFFALO,"RIFLE,5.56 MILLIMETER",1.0
カラム名を指定して抽出することも可能です。
$ csvcut -c county,item_name,quantity data.csv | csvlook | head | county | item_name | quantity | | ---------- | -------------------------------------------------------------- | -------- | | ADAMS | RIFLE,7.62 MILLIMETER | 1 | | ADAMS | RIFLE,7.62 MILLIMETER | 1 | | ADAMS | RIFLE,7.62 MILLIMETER | 1 | | ADAMS | RIFLE,7.62 MILLIMETER | 1 | | ADAMS | RIFLE,7.62 MILLIMETER | 1 | | ADAMS | RIFLE,7.62 MILLIMETER | 1 | | BUFFALO | RIFLE,5.56 MILLIMETER | 1 | | BUFFALO | RIFLE,5.56 MILLIMETER | 1 |
また、csvcut
を使用すると、カラムを指定した文字列の検索を行うことができます。
下記は county
列において LANCASTER
という文字列で検索を行っている例です。
$ csvcut -c county,item_name,total_cost data.csv | csvgrep -c county -m LANCASTER | csvlook | county | item_name | total_cost | | --------- | ------------------------------ | ---------- | | LANCASTER | RIFLE,5.56 MILLIMETER | 120 | | LANCASTER | RIFLE,5.56 MILLIMETER | 120 | | LANCASTER | RIFLE,5.56 MILLIMETER | 120 | | LANCASTER | RIFLE,5.56 MILLIMETER | 120 | | LANCASTER | RIFLE,5.56 MILLIMETER | 120 | | LANCASTER | RIFLE,5.56 MILLIMETER | 120 | | LANCASTER | RIFLE,5.56 MILLIMETER | 120 | | LANCASTER | RIFLE,5.56 MILLIMETER | 120 | | LANCASTER | RIFLE,5.56 MILLIMETER | 120 | | LANCASTER | RIFLE,5.56 MILLIMETER | 120 | | LANCASTER | LIGHT ARMORED VEHICLE | 0 | | LANCASTER | LIGHT ARMORED VEHICLE | 0 | | LANCASTER | LIGHT ARMORED VEHICLE | 0 | | LANCASTER | MINE RESISTANT VEHICLE | 412,000 | | LANCASTER | IMAGE INTENSIFIER,NIGHT VISION | 6,800 | | LANCASTER | IMAGE INTENSIFIER,NIGHT VISION | 6,800 | | LANCASTER | IMAGE INTENSIFIER,NIGHT VISION | 6,800 | | LANCASTER | IMAGE INTENSIFIER,NIGHT VISION | 6,800 |
データの並び替え
csvsort
を使用すると、指定した列の値を使用して行の並び替えを行うことができます。
下記は上記の結果からtotal_cost
列の値を使用して並び替えを行っている例です。
$ csvcut -c county,item_name,total_cost data.csv | csvgrep -c county -m LANCASTER | csvsort -c total_cost -r | csvlook | county | item_name | total_cost | | --------- | ------------------------------ | ---------- | | LANCASTER | MINE RESISTANT VEHICLE | 412,000 | | LANCASTER | IMAGE INTENSIFIER,NIGHT VISION | 6,800 | | LANCASTER | IMAGE INTENSIFIER,NIGHT VISION | 6,800 | | LANCASTER | IMAGE INTENSIFIER,NIGHT VISION | 6,800 | | LANCASTER | IMAGE INTENSIFIER,NIGHT VISION | 6,800 | | LANCASTER | RIFLE,5.56 MILLIMETER | 120 | | LANCASTER | RIFLE,5.56 MILLIMETER | 120 | | LANCASTER | RIFLE,5.56 MILLIMETER | 120 | | LANCASTER | RIFLE,5.56 MILLIMETER | 120 | | LANCASTER | RIFLE,5.56 MILLIMETER | 120 | | LANCASTER | RIFLE,5.56 MILLIMETER | 120 | | LANCASTER | RIFLE,5.56 MILLIMETER | 120 | | LANCASTER | RIFLE,5.56 MILLIMETER | 120 | | LANCASTER | RIFLE,5.56 MILLIMETER | 120 | | LANCASTER | RIFLE,5.56 MILLIMETER | 120 | | LANCASTER | LIGHT ARMORED VEHICLE | 0 | | LANCASTER | LIGHT ARMORED VEHICLE | 0 | | LANCASTER | LIGHT ARMORED VEHICLE | 0 |