重複の取り除き
学生の成績、実験データ、営業実績や支店別売上高…。手入力にしても業務システムから出力されたデータにしても、集められたデータにはたいてい重複があります。普通は重複していても、そのまま計算しますが、場合によっては同じデータをまとめてしまいたいことがあります。
データの平均や分布を調べるよりは、出現したデータに何があるかを端的に知りたいようなときです。このような場合は、重複データを圧縮して、まとめて表示できれば便利です。つまり、同じデータは1つを残して、他は取り除いてしまうわけです。例えば、以下のデータがあるとします。
3
2
1
2
2
3
1
1
1
1
1から3までの数字をランダムに10個生成してあります。1と2と3が重複しています。出現した数字だけを知りたい場合、重複した数字は不要ですね。
そこで同じ数値が続いた場合は1つだけを表示して、他の数値を取り除くプログラムのuniqをユーティリティーパッケージで用意しています。使い方は簡単で以下のようにデータを受け取ると重複処理(連続した同じ数字を1つだけ出力)してくれます。
3
2
1
2
3
1
連続して2回出現した2と連続4回の1がそれぞれ1つだけ出力されています。重複を全て排除した1と2と3だけを出力していないことに注意してください。あくまで連続して同じ数字でなかったときに、重複していないと判断して出力します。
2 ⇒同じ数字が連続していないからそのまま出力
1 ⇒同じ数字が連続していないからそのまま出力
2 |
2 | 連続して2回同じ数字⇒2を1つだけ表示して、残りは取り除く
3 ⇒同じ数字が連続していないからそのまま出力
1 |
1 |
1 |
1 | 連続して4回同じ数字⇒1を1つだけ表示して、残りは取り除く
もし、完全に重複をチェックしたい場合は、以下のように一度並べ替えを行なってから、uniqプログラムに引き渡せばOKです。1と2と3だけが出力されます。
1
2
3
ここでは、rpnのsortプログラムを使っていますが、以下のようにDOSコマンドのsortでも構いません。同じ結果が得られます。
1
2
3
横方向の重複処理
ちなみに他のrpnプログラムと同じように、uniqにも横に表示するタイプがあります。ダッシュ付きのuniq'で、使い方はuniqと同じです。例で説明しましょう。
以下のrpn式で先ほどの1から3までの数字が10個並んだ数列を横方向に表示してみます。
3 2 1 2 2 3 1 1 1 1
縦一列の数字をfoldプログラムで横一列に変換しています。この数列を横方向に重複処理してみましょう。
3 2 1 2 3 1
先ほどと同じ結果が横方向に処理されています。上記同様に完全に重複数字を1つにまとめるなら、以下のように横方向に並べ替えてからuniqにデータを渡します。
1 2 3
期待したとおりの出力が得られていますね。
行列データの重複チェック
このuniq'プログラムは複数行にも対応していますので、以下のような処理も一気に行なうことができます。まずは1から10までのランダム数字を行列として、10行10列分用意します。
9 10 7 5 9 4 10 7 4 1
9 8 9 6 9 1 4 1 3 6
4 5 6 5 6 5 2 9 4 10
6 1 2 3 4 4 5 7 7 5
2 6 8 2 8 3 1 5 1 6
8 4 5 8 7 9 10 3 10 4
1 10 2 5 6 3 9 7 2 5
10 4 6 4 4 8 8 6 2 10
3 8 3 2 3 8 10 2 7 9
7 7 7 7 5 6 7 5 2 2
これを横一列毎に、重複した数字を一気にまとめることができます。
1 4 5 7 9 10
1 3 4 6 8 9
2 4 5 6 9 10
1 2 3 4 5 6 7
1 2 3 5 6 8
3 4 5 7 8 9 10
1 2 3 5 6 7 9 10
2 4 6 8 10
2 3 7 8 9 10
2 5 6 7
パイプを3つ繋げて処理していますが、期待したとおりの結果になっていることが確認できます。sort'プログラムもuniq'と同様な処理ができるので、協調作業ができているわけですね。
uniq'は150個の数値、uniqは1000個の数値程度を目安に使用してください。
本講座で使用したプログラムは、ユーティリティーパッケージとして購入することができます。xypとnpdはrpnの姉妹ソフトウェアです。詳しくはプロダクトを参照ください。