macroscope

( はてなダイアリーから移動しました)

わたしがよくつかうデータ形式 (1) 論理的構造 ... たてよこの表、不完全な正規化

【まだ書きかえます。どこをいつ書きかえたかを必ずしも明示しません。】

- 1 -
データを、計算機上でつかうために、どんな形でもつか、という問題がある。それは、もちろん、どんな対象のデータであって、どんな目的でつかうかにもよる。ここでは、わたしが、気象観測データや天気記録を、研究および大学教育のためにつかうばあいを想定する。

データの提供もとはたくさんある。観測内容は、現代の気象観測ならば WMO (世界気象機関) の指針でだいたいそろっている。しかし、そのばあいも、データ形式は提供もとごとにまちまちである。(気象庁のたぐいどうしのデータ交換のために WMO がきめた形式はあるのだが、それは研究むけに便利ではなく、研究者がその形でデータをもらうことはあまりない。) 観測機器に付属するデータロガーという装置に特有の形式のこともある。紙に記録されていたものを自分で計算機入力することもある。一方で、あとの計算機処理のためには、なるべく計算機にとって単純な形式に統一しておきたい。他方で、異常値があれば、自然現象として異常なことがおきたかもしれないが、なにかのまちがいかもしれない。そこで、データファイルを文字で表示して目で見て異常値が見えやすく、また、形式を統一する前の段階にさかのぼりやすい形式にしておきたい。

格子点データは別として[注]、観測点ごとの観測値のデータや、観測点一覧表などを、わたしは、テキストファイルで、縦横の表(ひょう、table)の形でもつことが多い。ここで、表形式のほうがどちらかというと「論理的」な形式であり、テキストファイルはその表を収録するための一段「物理的」に寄った形式である。(しかし、ハードディスクの磁化か、紙の表面の光の反射率か、などといった物理的な記録様式にくらべれば「論理的」である。)

  • [注] 気象は3次元空間に分布し時間変化する現象だから、時空間の4次元 (あるいはそのうちえらばれた次元) のそれぞれを規則的にきざんだ格子点あるいは升目ごとに値をもつような格子型データをつかうこともある。ただし、ほとんどのばあい、観測は格子点でおこなわれているわけではないので、格子点データは統計処理やシミュレーションをへてつくられたものである。そのようなデータについては、わたしは、(3次元以上ならば2次元の断面をきって) 2次元の画像として可視化し、異常値や空間分布の特徴的なところだけ数値を数字で見るというつかいかたをすることが多い。そのようなデータの一段「物理」寄りの形式を自分でえらぶばあいは、計算機での浮動小数点数または整数の内部表現であらわされた数値が格子点の数だけ連続した形の単純なバイナリデータにすることが多い。この種類のものはこの記事の本題からはずすことにする。

この記事は第1部として「表形式」について考えることをのべる。まえに プログラム言語 Awk の教材として書いたページ [Awkで扱われる論理的標準データ形式: 表]を改訂・補足したものである。

つぎの記事で第2部として「テキストファイル」について考えることをのべる。同じく、[わたしがAwkで扱う「物理的」標準データ形式: 表を表現する空白区切りのテキストファイル] を改訂・補足したものである。

- 2 -
データに即して構造を考えると、3次元以上の表にしたほうがよいこともある。しかし、人が目で見て認識しやすいのは2次元であり、3次元以上はむずかしい。そこで、理屈のうえでは3次元以上の構造をもつものも2次元の表にわけて表現することにする。

2次元の表とは、縦と横にそれぞれ一定の個数の升目がならんだ形のものである。

縦の要素を1つだけにして横に見たものを「行」(英語では row)、横の要素を1つだけにして縦に見たものを「列」(column) とよぶことにする。どの行も同じ数の列、どの列も同じ数の行をもつとする。表の升目の数は {行の数 × 列の数} である。たとえばつぎの表は 2行3列 である。

A1B1C1
A2B2C2

人が見るための表では、升目を合併して、複数の列にまたがる、あるいは、複数の行にまたがる 升目をつくることがある。人がとらえる情報の内容にとってそれがふさわしいことがある。しかし、計算機処理にとっては、行と列の数がそろっていない表はとてもあつかいにくい。ここでは、升目の合併はしないときめる。そのかわりの表現方法はばあいごとに考えるが、単純な案は、合併対象となるそれぞれの升目に同じ内容を入れておくことである。

ここまでならば、行と列のやくわりは対等で、縦と横をいれかえてもよい。

- 3 -
ここから、表のつかいかたを、データベースの理論のうちの「関係データベース」(relational database, RDB) でいう表にあわせることにする。ただし、わたしは気象データをRDBにいれてつかっているわけではない。わたしがここでのべるように表をつかうようになったのは、Awk 言語をつかう習慣からきている。Awk 言語は Unix オペレーティングシステムといっしょに発達し、Unix は早い段階からシステム管理情報を RDB であつかっていたから、Awk であつかいやすい表と RDB でいう表との特徴がだいたい同じなのは偶然ではないだろう。

ここで、表の行と列のやくわりは対等ではない。列はそれぞれちがった属性をあらわしている。列を単純に入れかえると表の意味がかわってしまう。(それぞれの列に固有名をつけておいて、固有名こみで入れかれれば、意味をたもつことができる。) 行は属性群の1回の出現をあらわしている。行の出現順序は原則として意味をもたず、行を単純に入れかえても表の意味はかわらない。(実際には、とくに時系列的観測値のばあい、出現順序を現実世界の時間の順序にあわせるのが正しいとすることが多いが。)

- 4 -
ちかごろ、表形式のデータのもちかたについて、"tidy data" 、日本語では「整然データ」が望ましいという議論がある。わたしは、西原 史暁 (Fumiaki Nishihara) さんによるウェブページ「整然データとは何か」(2017年1月9日) https://id.fnshr.info/2017/01/09/tidy-data-intro/ で知った。基本文献はつぎのものである。

わたしは まだ きちんと照合していないのだが、これは、RDBの理論でいう「正規化」(normalization)と、基本的に同じことだと思う。

単純にいうと、他の列(複数の列の組でもよい) の内容がきまればきまってしまうような従属関係をもつ列は表にふくめず、従属関係をあらわす表を別につくることである。

こうすれば、みたすべき従属関係がみたされないという異常事態は出現しなくなるし、多くのばあいには計算機上の記憶容量の節約にもなる。

- 5 -
わたしは、表の正規化 あるいは「整然データ」の考えをもっともだと思い、それにあわせられると思うときはあわせている。

しかし、あわせる気になれないこともよくある。だから、わたしの常用のデータ形式は、かならずしも「整然データ」ではない。あわせない理由はいくつかのばあいがある。

- 5a -
表現したい内容が、時間と空間の次元、あるいは空間の2次元をもつばあい。わたしは、その2次元を1方向にならべず、画面(紙面)の2次元をつかって表現したい。

たとえば、複数の場所での複数の時刻の天気を表にするばあい、場所ごとに列、時刻ごとに行をもつような表をつくる。これはまさに西原さんが「整然データでない」例としてあげているものである。わたしは、画面上で表をながめることによって、同じ時刻の場所による天気のちがいや、同じ場所での時刻による天気のちがいを読みとることができることのほうを、データの正規化よりも優先する。

- 5b -
地球上の気象現象は明確な日周期と年周期をもつものがおおい。本来はひとつの時間軸だが、1日のうちの時刻を特別あつかいして横軸にとり、日付を縦軸にとる。たとえば毎日の午前6時の気温、毎日の正午の気温が、それぞれ縦にならんでいるほうが、わかりやすいことが多い。

- 5c -
われわれは日付を、近代・現代ならばグレゴリオ暦の年・月・日であらわす習慣がある。データ源はたいていそうなっているから、さかのぼってチェックするためにも、年・月・日は表に入れておきたい。(わたしは「日付型」をもたないプログラム言語でそだってきたので、年、月、日をそれぞれ整数値で別々の列に入れる習慣をもっている。) しかし、データは月の境目で分割せずに、(典型的には) 1年の毎日の値が1日1行で (時間きざみが1日よりもこまかいときは1日複数行で) ならんでいるものにしたい。その時系列をすなおにグラフにできるように、等間隔の時間目盛りを入れておきたい。時間きざみが1日ならば、わたしは1月1日を1とした通しの日付を整数値で入れる列をつくる。{年, 月, 日}の組と、通しの日付とは、相互に従属関係にあり、両方を入れることはあきらかに冗長である。しかし、わたしの作業効率のためには、同じデータファイルに両方があったほうがよい。

- 5d -
たくさんの地点の観測値をいっしょに表にすることがある。観測点には作業用のIDがつけられていて、観測点一覧表を見れば、IDから観測点の地名や国名を知ることができる。その条件のもとで、正規化がよいとするならば、観測値の表には、観測点IDを入れて、地名や国名は入れないのが正しい。しかし、わたしは地名や国名(の略称)を入れることがある。ひとつには、観測点ID をとりちがえて処理してしまうおそれがあるので、わざと冗長性をもたせたいことがある。もうひとつには、異常値 (現実世界の異常現象を反映しているばあいも、まちがいのばあいもありうるが) を見つけたとき、観測点一覧表をひくまでもなく地名がわかったほうがありがたいと思うことがある。