Perl Hackers Hub

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

この記事を読むのに必要な時間:およそ 1 分

データの値の簡便な解読

本節では,意味や役割のわかりにくい値の解読や,使われ方を知るためのコマンドを紹介します。紹介するdigitdemogは,1行ごとにデータを読み取り,文字列の出現パターンを集計することにより,(a)⁠b)も検出しつつ,符号化された文字列パターンの解読に使うことで(f)を解決に導きます。colgrepを意味の不明な値を持つ行の抽出に使えば,(b)⁠f)を解決に導きます。

各行各桁に出現した全文字の頻度集計 ─⁠─digitdemog

ある列の文字列の出現パターンを知る場合は,digitdemog注5が有用です。digitdemogの基本機能は,全行において各文字が何桁目に何回現れたかの出力です。

以下では,プロセス置換内でcsel -p11を使うことにより,T*0710.txtの11列目を取り出しています。

各文字が各行先頭から何文字目に何度出現したか。-.で追加のヒント
$ digitdemog -. <( csel -p11 T*0710.txt ) | expandtab
    1   2   3     4     5     6   7   8   9
'.' 0   1.  0     0     0     0   0   0   0
'0' 0   132 0     0     7     0   0   0   0
'1' 504 308 0     7     4     0   0   0   0
'2' 753 70  0     22    3     1.  0   0   0
'3' 102 13  0     7     3     0   0   0   0
'4' 0   10  0     0     0     0   0   0   0
'5' 0   96  0     0     2     0   0   0   0
'6' 0   312 0     0     11    0   0   0   0
'7' 0   31  1.    0     3     0   0   0   0
'8' 0   101 0     0     1     0   0   0   0
'9' 1.  286 0     0     3     0   0   0   0
'c' 0   0   1323. 0     0     36. 1.  0   0
'm' 0   0   0     1323. 0     0   36. 1.  0
'×' 0   0   36.   1.    0     0   0   0   0
end 134 0   0     0     1323. 0   0   36. 1.
※各値の末尾に仮想的な文字endを伴うと見なしている

この結果から,⁠ピリオド.は,先頭から2文字目に1回だけ出現する」0は,先頭から2文字目に132回,5文字目に7回現れ,ほかの場所には現れない」⁠空文字列が134個ある」ことがわかります。

文字列パターンの解読

上記でdigitdemogにオプション-.を与えたので,1.(8ヵ所⁠⁠,36.(4ヵ所⁠⁠,1323.(3ヵ所)のように出力数値にピリオドを伴うものがあります。これらは,同じ入力行に由来することを意味します。たとえば1323.と示された3ヵ所は,同じ1323行の各3箇所(3~5文字目)のそれぞれで定まる文字'c''m'endを数えています。

この追加のヒントから元データをもとに謎解きをすると,T*0710.txtの11列目の出現値は,空文字列(134個)『整数cm』⁠1323個)『整数×整数cm』⁠36個)『9.7×整数cm』⁠1個)のみ」とわかります。

この11列目は,単に文字列として扱うのではなく,各値から2個以内の数値を取り出す変換を行うのが良いでしょう。すると,大小比較や比の演算対象となる数として扱えるので,分析の観点から適切です。

注5)
後半のdemogはdemography(人口統計)の先頭部です。

指定列で正規表現検索 ─⁠─colgrep

colgrepは,指定列をgrepして該当する行全体を抽出します注6⁠。

以下では,表中の空文字列(以下,⁠空」とします)が何を意味するかの調査例として,ISBNコードが空欄の図書について調べています。

1列目のISBNコードが空の図書をすべて検出。cselでタイトルなどのみ表示
$ colgrep -c1 -e'^$' T*0710.txt | csel -p11,17,2
match:7 unmatch:1487 total:1494 (colgrep)
30cm    ¥1800   東京2020オリンピック公式ガイドブック
30cm    ¥1800   東京2020パラリンピック公式ガイドブック
21cm    ¥545    現代俳句 令和3年7月号
26cm    ¥8100   法令全書 令和3年5月号
30cm    ¥3000   賃金事情調査 令和2年
30cm    ¥4500   水産油脂統計年鑑 2020年
26cm    ¥1000   法と民主主義 NO.559(2021-6)

-c1-e'^$'により,1列目(ISBNコード)で正規表現^$にマッチ注7した行を出力します(1494行中7行⁠⁠。

上記の結果から,ISBNコードが何かの事情で未記載の,分析作業で注意を要する可能性のある図書7冊を把握できます。

特別値を持つ行の特徴を比較でとらえる

また別の少し実用的な例で試してみます。⁠11列目(本の大きさ)が空の場合」に何が起きたのかを調べます。

抽出した行全体についての性質をcolsummaryで調べる
$ colgrep -c11 -e'^$' T*0710.txt | colsummary
134 line(s) read;...
※11列目が空なら10,15,16,18列目もすべて空とわかる

比較のために,上記で抽出した行以外(-~指定)を調べる
$ colgrep -~ -c11 -e'^$' T*0710.txt | colsummary
1360 line(s) read;...
※比較してわかることは,すべてが空でないのは10列目のみ

ここではcolsummaryも併用しています。別の列との関係をきちんと把握するには,11列目が空でない場合の行の様子と比較する必要があります。そのため,2つ目のコマンドではcolgrepにオプション-~を与えて,1つ目のコマンドの検索条件を反転しています。

紙幅の都合で出力は省略しましたが,それぞれ図2に似た出力2個が得られます。それを見れば※コメントのようなことが確認できるので,⁠11列目が空」「10列目(ページ数など)が空」がわかります(⇔は2個の命題の真偽が一致することを表します⁠⁠。図書の「ページ数」が決まってないなどの理由で情報がない場合は,⁠大きさ」の情報もありません。逆もしかりです。

このようにcolgrepcolsummaryを使った比較で,特別値の意味を探ることができます。

注6)
grepは文字列検索のUNIXコマンドであり,正規表現が使えます。
注7)
^$は行頭^と行末$の間に文字がない,つまり,空を意味します。

まとめ

本稿は,表形式のテキストデータを目で見て理解可能にするPerl製コマンド群を紹介しました。列の特徴量を整理して表示したり,複数のデータの重なり具合を把握できたり,値の書式の解読などに使えたりするコマンド群で,データ分析上の困難がどう解決するかの一端を示しました。このようなコマンドの機能で,世の中で蓄積されて眠ったままのデータが有効活用されることを願っています。

さて,次回の執筆者は礒部浩行さんで,テーマは「Rest APIフレームワークRaisinを使ってみよう」です。お楽しみに。

WEB+DB PRESS

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

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

  • 特集1
    開発環境から本番環境まで一気通貫!
    実践コンテナ活用
    VS Code,Docker,Kubernetes,Azure
  • 特集2
    iOS 15開発最前線
    Swift 5.5,UI開発,通知管理,Xcode Cloud
  • 特集3
    作って学ぶ検索エンジンのしくみ
    Goで実装! 膨大な情報からどう高速に探すのか

著者プロフィール

下野寿之(しものとしゆき)

普段はデータ分析のお仕事。最近は新型コロナ関係が多め。自由度2のt分布や楕円球を使った数理モデルで数値の意味を近年考えている。16年前に量子計算で博士を取得し,7年前に医学統計学を学ぶ。

GitHub:tulamili
SlideShare:https://www.slideshare.net/shimonotoshiyuki