昨日、たまたまYouTube見てたら「PHPの連想配列」について解説するというのがありました。
要するに配列には「キー」を与えて、そこに「値」を格納するわけです。一般に配列のキーは整数で、コンパイラ言語ではあらかじめ配列の数を事前に確保しておきます。data[99]とすれば、data[0]からdata[99]までの100個分の領域をメモリ内に確保して、アドレスはdata[0]を指しているのだろうと思います。
それに比べると連想配列のキーは文字列でも整数でも構わず、数も成り行きでいいのは、コンパイラではなくインタプリタだからだと思いますが、基本的には、動的にメモリを確保することができるからでしょう。
ハッシュテーブルを使って値を格納していくため、出力は入力順にはなりませんが、キーを当てればハッシュテーブルから値を取り出してくるので速度は結構早いのが特徴と言えます(ハッシュテーブルはバランスが悪いと遅くなると入れており、バランスをどのようにとるかが速度に影響を持つと教わりました)。
で、あるコードを基準に集計するとして、それぞれのコードに3種類とか4種類の集計するべき対象(値)があるとします。
まず、すべてのコードに対して集計をしてみます。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 |
BEGIN{ FS="\t"; } { if($53=="0000-00-00"){ if($41<=5) d1[$44 $46 "\t" $45 $47]+=1; else if($41<=10) d2[$44 $46 "\t" $45 $47]+=1; else if($41<=30) d3[$44 $46 "\t" $45 $47]+=1; else d4[$44 $46 "\t" $45 $47]+=1; } } END{ for(i in d1) print "5年以内\t" i "\t" d1[i]>"051.txt"; for(i in d2) print "10年以内\t" i "\t" d2[i]>"052.txt"; for(i in d3) print "30年以内\t" i "\t" d3[i]>"053.txt"; for(i in d4) print "永年\t" i "\t" d4[i]>"054.txt"; } |
53列目のデータが「0000-00-00」の時だけを集計の対象にしています。それを「5以下」「10以下」「30以下」「それ以上」の4区分で集計するために、それぞれ「d1」「d2」「d3」「d4」と言う連想配列をつかって集計しています。
連想配列のキーは「$44 $46」が組織コード、「$45 $47」が組織名で間にタブ入れています。
その結果を「051.txt」「052.txt」「053.txt」「054.txt」として標準出力に出力しています。awkで連想配列を出力する標準的な方法は「for」文にキーと連想配列名で出力します。
標準出力に室力する場合は「>」を使いますが、追記する場合は「>>」と2個付けます。
ただし、この方法だと出力順が不定になりますので、通常はExcelなどでソートして使います。
このケースの場合、それぞれのコードに該当するデータがないこともありExcelを使ってソートなどしながらコードに合わせて4種類の出力結果を並べるのには結構時間を要します。そこで、
05t.awk
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
BEGIN{ FS="\t"; } FLG==1{ d1[$2]=$4; next; } FLG==2{ d2[$2]=$4; next; } FLG==3{ d3[$2]=$4; next; } FLG==4{ d4[$2]=$4; next; } { print $1 "\t" $2 "\t" d1[$1] "\t" d2[$1] "\t" d3[$1] "\t" d4[$1]; } |
FLGが「1」の間はd1にキーを「コード」、値に「集計値」を格納します。
同様に、FLGが「2」の間は「d2」に、FLGが「3」の間は「d3」、FLGが「4」の間は「d4」にキーと集計値を格納します。
1 2 |
awk -f script\05t.awk FLG=1 051.txt FLG=2 052.txt FLG=3 053.txt FLG=4 054.txt ssk.txt>05t.txt |
で、最後の「ssk.txt」で、コード順に連想配列からコード(キー)が合致している値を4種類取り出して出力していきます。連想配列にコードが該当しなければ「ヌル」になります。
こうすることで、連想配列から出力された区分ごとの集計結果を組織コード順に出力することができます。Accessなどを使えばVBAを使わずにテーブルをコードでつないでコード順に出力させることは可能ですが、awkでも実に簡単簡明に実現することができます。
500万件あっても数秒だと思いますからAccessよりはきっと格段に速いと思いますし、Excelでは読み込むことすらできません。