MAGAZINE
ルーターマガジン
Ruby
Rubyでcsvファイルを横持ちから縦持ち構造に変換する
2020.07.29
こんにちは。学生アルバイトのohkiです。みなさん、テーブル構造というとどんなものを思い浮かべるでしょうか?おそらく多くの方が横持ち構造を思い浮かべるのではないかと思います。確かに横持ち構造の方が見やすいですが、縦持ち構造の方が扱いやすい場合もあります。そこで、今回はcsvファイルを横持ち構造から縦持ち構造に変換する方法を紹介します。
縦持ちとは
カラムを横に並べたテーブルのことを横持ちというのに対して、縦持ちは1行に1つの情報のみを格納したテーブルのことです。縦持ちのメリットとしては、カラムの追加や削除に柔軟に対応できます。例えば、カラムを追加するときに、横持ちの場合はテーブル定義を変更する必要がありますが、縦持ちの場合は、テーブル定義はそのままで、行が増えるだけです。また、テーブルがスパースな場合は、縦持ちの方が行数が少なくなり、コンパクトになります。
| name | gender | age | flag |
|---|---|---|---|
| Tom | male | 20 | 0 |
| John | male | 22 | 0 |
| name | カラム | 値 |
|---|---|---|
| Tom | name | Tom |
| Tom | gender | male |
| Tom | age | 20 |
| Tom | flag | 0 |
| John | name | John |
| John | gender | male |
| John | age | 22 |
| John | flag | 0 |
Rubyで縦持ち構造に変換する
では、csvファイルを縦持ち構造に変換していきたいと思います。今回は以下の横持ちcsvファイルを例に実行していきたいと思います。
#meibo.csv "name","gender","age","flag" "Tom","male","20","0" "John","male","22","0" "Paul","male","43","1" "Alice","female","31","0"
以下が実行コードになります。元の横持ちcsvを1行ずつ読み込んでいき、nameカラムを属性として縦持ちに変換していきます。また、"headers: true"を与えることで、先頭行をヘッダとして扱うことができます。ここでの"csv_row"のクラスはCSV::Rowであり、ハッシュのようにカラム名でフィールドにアクセスする事ができます。
require 'csv'
def unpivot_csv(csv_name, output_csv_io=STDOUT)
CSV.foreach(csv_name, encoding: 'BOM|UTF-8', headers: true) do |csv_row|
csv_row.each do |head, field|
output_csv_io.puts( [ csv_row['name'], head, field ].join(",") )
end
end
end
unpivot_io = File.open('./unpivot_meibo.csv','w')
unpivot_csv('./meibo.csv', unpivot_io)
unpivot_io.close
生成ファイルは以下のようになります。
#unpivot_meibo.csv Tom,name,Tom Tom,gender,male Tom,age,20 Tom,flag,0 John,name,John John,gender,male John,age,22 John,flag,0 Paul,name,Paul Paul,gender,male Paul,age,43 Paul,flag,1 Alice,name,Alice Alice,gender,female Alice,age,31 Alice,flag,0
まとめ
今回はcsvファイルの縦持ち変換について紹介しました。これからは、用途に合わせてcsvの構造を使い分けていきましょう。
CONTACT
お問い合わせ・ご依頼はこちらから