Perl Hackers Hub

第69回表形式データを操るUNIXシェル型Perl製コマンド群 ―ビッグデータ時代の汎用的なデータ整備と分析のために(1)

本連載では第一線のPerlハッカーが回替わりで執筆していきます。今回のハッカーは、デジタルガレージにてデータ分析のお仕事をしている下野寿之さんで、テーマは「表形式データを操るUNIXシェル型Perl製コマンド群」です。各コマンドの実体はPerlで書かれた単体で動くプログラムで、単独または既存のコマンドと組み合わせて実行します。

本稿のサンプルコードは、WEB+DB PRESS Vol.124のサポートサイトから入手できます。

データ分析の難しさ

ビッグデータやデータサイエンスという言葉がよく使われ始めて何年も経ちますが、企業に蓄積されたPOSや人事などのデータを存分に活用するのは、まだいろいろと厳しいのが現実です。

データには不具合がある

現場のデータには、次のような不具合が多数あります[1]⁠。

  • (a)不要なデータの混入[2]
  • (b)仕様書未記載かつ担当者も知らない特別値[3]
  • (c)データの欠損[4]
  • (d)ある列で特定の値が不自然に頻発[5]
  • (e)複数の表データ間での不整合[6]

そのため、不具合を簡潔に調べる手段が必要です。

使用するデータの選定が難しい

次の理由により、多数のデータからどの部分を本格的な分析に使うかを決める手間も、際限なく増えがちです。

  • (f)各列の(符号や略語や特別値)の意味が不明
  • (g)1枚の表が持つ列数が過多[7]
  • (h)1枚の表に酷似した列が複数[8]
  • (i)異なる表に同じ意味の列が過多[9]
  • (j)提供された表の枚数が過多[10]

そのため、分析に使う可能性のある表と列を網羅的に簡潔に調べる手段が必要です。

既存ソフトウェアの問題点

UNIX系コマンドや、Pythonライブラリのcsvkitやpandas_profiling、R言語、既存の商用ソフトウェアでは、(a)(j)の10項目への対処は困難です。(a)(e)の実務データの不具合への対処は、初歩的には可能でも全貌の把握は困難です。教科書的な基礎統計量(平均や最大、最小など)を算出するユーティリティは多いですが、ありがちな特別値-1999や空欄など)を含む符号化された文字列データを解読するには、アドホックな操作が必要で汎用性に難があります。(f)(j)の使用するデータの選定も、目的に見合った容易さではプログラミングできません。たとえば、全3列のデータに対して2列目を末尾(右端)に移動したい場合[11]はAWKでawk '{print $1,$3,$2}'と書けばよいものの、12列もある場合は、12列分をコマンドラインに入力するか、for文を使ったプログラミングを行う必要があります。これらは1回ではなかなか正しく書けないため、デバッグ作業が発生して本来の分析目的に集中しづらくなり(f)⁠g)⁠h)で起こる問題の解決を遠ざけます。(i)⁠j)はなおさら難しいです。

表形式データを扱う新しいPerl製コマンド群

上記の現状を打破すべく、UNIXコマンドとして動くプログラムをPerlで作り、CPANモジュール化しました。本稿ではそのうちの8個を紹介します。

Perl製コマンドのメリット

(a)(j)に対処するプログラムの動作は、CPUリソースよりもデータ記憶装置からの読み取り速度が律速する場合が多いです。そのため、C++言語などを採用する必然性は低く、スクリプト言語の中で、文字列処理、多次元配列や多次元ハッシュなどの構文が書きやすいPerlを採用しました[12]⁠。Perlは後方互換性が高いので、今作ったプログラムが50年後も使える見込みが高いのも理由です。

インストール方法

本稿で使う各コマンドは、App::を前置したモジュール名を指定してインストールします[13]⁠。

8個のコマンドを逐次インストールする場合
$ cpanm App::csv2tsv
$ cpanm App::csel
$ cpanm App::expandtab
$ cpanm App::crosstable
$ cpanm App::colsummary
$ cpanm App::venn
$ cpanm App::digitdemog
$ cpanm App::colgrep

8個のコマンドを一括インストールする場合
$ cpanm App::Bin4TSV::8

plenvを使っている場合は、各コマンドを利用可能とするため以下を実行
$ plenv rehash

これらのコマンドは、Perl 5.14(2011年5月リリース)以降で動作します[14]⁠。本稿の各コマンドの動作は、Perl 5.18.4とPerl 5.32.1で確認しました。

コマンドの共通オプション

各コマンドには、そのコマンド独自のオプションのほかに、コマンド間で共通するオプションがあります。たとえば-jは、出力を日本語表記にすることを指定するためのものです。-~は、何かの機能を反転するときに使います。

いくつかのオプションは、パラメータを持ちます。-m0など0を伴う場合の多くは、何かの機能の抑制の指定です。-iは、タブ文字以外への入力の列区切り文字の指定です。-gは、何かの抽出指定数の指定です。

各コマンドのマニュアルは、各コマンドに--helpを付与して実行すると表示されます。

扱うデータはTSV形式

多くのデータは表形式で、SQLのテーブルのように行(レコード)と列(属性)からなります[15]⁠。表形式のデータはCSVComma-Separated Valuesカンマ区切り)形式が多いですが、本稿ではCSVの亜種であるTSVTab-Separated Valuesタブ区切り)形式のデータを処理します。CSV形式は引用符囲みやエスケープ文字の処理がやっかいなためです。

自由に使えるTSVファイルとしては、国立国会図書館のオープンデータセットなどがあります。

CSV形式からの変換 ─⁠─csv2tsv

CSV形式のファイルをTSV形式に変換する場合は、csv2tsvを使います[16]⁠。

CSV形式をTSV形式に変換。リダイレクション(<)の使用が望ましい
$ csv2tsv < foo.csv > foo.tsv

自在な列操作 ─⁠─csel

便利さに長年の定評があるAWKをさらに便利にすべく、cselを作りました。たとえば、csel -p3..7により、3~7列目だけを出力します。

1行12列のTSVファイルの作成
$ perl -E'say join"\t",1..12' | tee c12.tsv
1   2   3   4   5   6   7   8   9   10  11   12

-pで指定列のみ抽出。「..」は範囲指定。AWKより簡単
$ csel -p3..7 c12.tsv
3   4   5   6   7

-dで指定列を出力抑制。「,」は連結指定。AWKだと難しい
$ csel -d3..7,10,12 c12.tsv
1   2   8   9   11

-hで指定列を先頭(左端)に移動。「12..10」は逆順指定(12,11,10)
$ csel -h12..10 c12.tsv
12  11  10  1   2   3   4   5   6   7   8   9

-tで指定列を末尾(右端)に移動。レイアウトを崩す列の移動に実用的
$ csel -t9,6 c12.tsv
1   2   3   4   5   7   8   10  11  12  9   6

列を縦ぞろえで表示 ─⁠─expandtab

表形式のデータは、lessで中身を見ても、同じ列が縦にそろわず画面で読みにくい場合があります。その場合はexpandtabを使います。expandtabは、全列が縦にそろうように、各列の最も幅の広い文字列に合わせて各値の右側に半角空白を補填します。

次の例では、Amazon Linuxのパスワードファイル/etc/passwdに対して実行しています。

-sで与えた閾値より幅広な文字列があると、その行の残りの列は狭くなる
$ expandtab -i: -c🔷 -s15 /etc/passwd

実行結果は図1です。

図1 expandtabでAmazon Linuxの/etc/passwdを縦ぞろえ
図1 expandtabでAmazon Linuxの/etc/passwdを縦ぞろえ

ファイルがタブ区切りではない場合は、-iオプションで区切り文字を指定します。ここでは/etc/passwdの区切り文字である:を指定しました。

数値パラメータ付きの-sオプションにより、できるだけ多くの列の先頭を縦にそろえつつ、出力表の横幅を縮めることができます[17]⁠。

<続きの(2)こちら。>

WEB+DB PRESS

本誌最新号をチェック!
WEB+DB PRESS Vol.130

2022年8月24日発売
B5判/168ページ
定価1,628円
(本体1,480円+税10%)
ISBN978-4-297-13000-8

  • 特集1
    イミュータブルデータモデルで始める
    実践データモデリング

    業務の複雑さをシンプルに表現!
  • 特集2
    いまはじめるFlutter
    iOS/Android両対応アプリを開発してみよう
  • 特集3
    作って学ぶWeb3
    ブロックチェーン、スマートコントラクト、NFT

おすすめ記事

記事・ニュース一覧