並べ替え
もう少し長期の黒点数の推移を見てみましょう。以下のデータは1979年から2008年の30年間の年平均黒点数データです。なお、データはdata.txtに格納されているとします。
157 142 145 94 54 29 17 8 21 64
93 119 111 104 63 40 29 15 7 2
30年間の黒点数の推移
最初の数値155が30年前の年間平均の黒点数、157が20年前の年間平均の黒点数、93が10年前の年間平均の黒点数の順でデータが並んでいます。この30個のデータをグラフにしてみましょう。
>xyp -x,30 -y,200 -s10,50 -m <tmp
^y 200
|
|
-** *
| * **
|
| * **
- * * *
| *
|
| * * * *
- *
| * * * *
| * * * * x
|o * * *3*
+------------|------------|------------>
黒点数はきれいな周期性を持っているようです。30年で3回のピークと3回のボトムがあることが分かります。
黒点数を少ない順に並べる
ちなみに、ボトムはどれくらいの黒点数なのでしょうか。黒点数を並べ替えてみましょう。まず、data.txtを縦一列に変換します。
155
154
140
:
:(中略)
:
15
7
2
長すぎるので途中を省略しましたが、縦一列に変換できていることが分かります。次に並べ替えるためにユーティリティーパッケージのsortプログラムを繋げます。
2
7
8
:
:(中略)
:
154
155
157
途中を省略しましたが、rpnのsortプログラムを使うことでm行1列のデータを並べ替えることができます。
少ない順のトップ10
次にトップ10を出してみましょう。トップ10を出すには、まず並べ替えてから行番号を付与して、最後にlookupを使って1から10までを抽出します。
>rpn @x 1 + #x @x x <tmp | rpn 1 10 -c lookup
1 2
2 7
3 8
4 13
5 15
6 17
7 17
8 21
9 29
10 29
ちょっと説明すると、最初のrpn式のfold'で30個のデータを縦一列に変換して、sortで並べ替えします。tmpには並べ替え終わったデータが縦一列に並んでいます。次のrpn式で行番号を付与して、lookupで1から10までのデータを抽出する流れになっています。
黒点数が少なかった1位から10位までが出ていますね。結果を見ると30年間で年平均黒点数が10個以下だった年は3年しかなかったことになります。見方を変えると平均すれば10年に1年は10個以下ということになります。
横一列のデータも簡単に並べ替え
さて、rpnプログラムのfoldにfold'があったのと同じように、sortプログラムにもsort'という親戚があります。sortはm行1列のデータを並べ替え、sort'は1行n列のデータを並べ替えるプログラムです。
試しにsort'プログラムを使ってみましょう。まず、data.txtを横一行に変換します。
155 154 140 115 66 45 17 13 29 100 157 … 64 93 119 111 104 63 40 29 15 7 2
画面に入りきらないので途中を省略しましたが、横一行に変換できています。ここでfold'に指定した36は36個のデータで折り返すようにというものです(36は3年×12ヶ月)。
data.txtには12列×3行の形でデータが格納されているのですが、fold'への指定から36個集めてから折り返えそうとするために、結局は全部のデータが一行になって出力されています。
2 7 8 13 15 17 17 21 29 29 29 … 100 104 111 115 119 140 142 145 154 155 157
これも画面に入りきらないので中略しましたが、横一行に並べ変わっていることが分かりますね。
tmatを使って行列の縦横変換をすれば、'(ダッシュ)付きのプログラムは必要ないのですが、ユーザが素早く計算しやすいようにfold、fold'、sort、sort'のような縦一列、横一行のデータに対応したプログラムを完備しました。
大きいもの順に並べる
前述の並べ替えは昇順(小さいもの順)でしたが、降順(大きいもの順)にするにはどうすればいいでしょう。rpnではユーティリティーパッケージのreverseプログラムを使って逆順にします。
以下は先ほどの並べ替えの例です。data.txtを縦一列のデータにしてからsortに引き渡しています。
2
7
8
:
:(中略)
:
154
155
157
並べ替え済みのデータが確認できたので、このデータをreverseプログラムに引渡します。
157
155
154
:
:(中略)
:
8
7
2
きちんと逆順に並んでいることが分かります。直近30年間で年平均の黒点数が200を超えることはなかったようです。実は300年以上の観測歴史の中で黒点数が150を超えたのは1778年、1947年、1957年~1959年、1959年、1979年~1980年、1989年の8年しかありません。
直近30年間の前の270年間で150個以上発生した年は5年だけですから、1.85%の確率です。つまり、大体50年に1回しか発生しないわけです。それが直近30年間で3回発生していましたから、太陽の活動はとても活発な時期だったことになります。
横一列のデータを大きいもの順に並べる
では横に並んでいるデータを逆順にするにはどうすればいいでしょうか。残念ながらreverse'は存在しません。代わりに、rpnには「u」というスタック操作記号があります。uを使うと横方向の逆順と同じ効果が得られます。「rpn u」は「rpn -c reverse'」と思ってください。具体例を示しますね。
155 154 140 115 66 45 17 13 29 100 157 … 64 93 119 111 104 63 40 29 15 7 2
fold'でdata.txtを横一行に変換します。
2 7 8 13 15 17 17 21 29 29 29 … 100 104 111 115 119 140 142 145 154 155 157
sort'を繋いで、横一行のデータを昇順に並べ替えます。
157 155 154 145 142 140 119 115 111 104 100 … 29 29 29 21 17 17 15 13 8 7 2
最後に並べ替えられた横一行のデータをuで逆順にします。
sort'は150個の数値、sortは1000個の数値程度を目安に使用してください。
uは150個の数値、reverseは1000個の数値程度を目安に使用してください。
本講座で使用したプログラムは、ユーティリティーパッケージとして購入することができます。xypとnpdはrpnの姉妹ソフトウェアです。詳しくはプロダクトを参照ください。