AWKを使用して数値データの列の中央値を計算するにはどうすればよいですか?
単純なアルゴリズムを考えることはできますが、プログラムすることはできないようです。
私がこれまでに持っているのは:
sort | awk 'END{print NR}'
そして、これは私に列の要素の数を与えます。これを使用して、特定の行(NR/2)
を印刷したいと思います。 NR/2
が整数でない場合は、最も近い整数に切り上げ、それが中央値です。それ以外の場合は、(NR/2)+1
と(NR/2)-1
の平均を取ります。
このawk
プログラムは、数値的にソートされたデータの1列を想定しています。
#/usr/bin/env awk
{
count[NR] = $1;
}
END {
if (NR % 2) {
print count[(NR + 1) / 2];
} else {
print (count[(NR / 2)] + count[(NR / 2) + 1]) / 2.0;
}
}
使用例:
sort -n data_file | awk -f median.awk
awk
を使用すると、値を配列に格納し、最初の列を見ると仮定して、最後に中央値を計算する必要があります。
sort -n file | awk ' { a[i++]=$1; } END { print a[int(i/2)]; }'
確かに、実際の中央値の計算では、質問で説明されているように丸めを行います。
sort -n file | awk ' { a[i++]=$1; }
END { x=int((i+1)/2); if (x < (i+1)/2) print (a[x-1]+a[x])/2; else print a[x-1]; }'
中央値を計算する配列がある場合(Johnsywebソリューションのワンライナーを含む):
array=(5 6 4 2 7 9 3 1 8) # numbers 1-9
IFS=$'\n'
median=$(awk '{arr[NR]=$1} END {if (NR%2==1) print arr[(NR+1)/2]; else print (arr[NR/2]+arr[NR/2+1])/2}' <<< sort <<< "${array[*]}")
unset IFS
このAWKベースの回答 unix.stackexchange.comの同様の質問に対して、中央値を計算するためのExcelと同じ結果が得られます。
OK、このトピックを見て、過去に似たようなものを探していたので、2セント追加できると思いました。タイトルにawk
と書かれていても、すべての回答はsort
も使用しています。データの列の中央値の計算は、 datamash :で簡単に実行できます。
> seq 10 | datamash median 1
5.5
ソートされていない列がある場合でも、sort
は必要ないことに注意してください。
> seq 10 | gshuf | datamash median 1
5.5
ドキュメントには、実行できるすべての機能と、多くの列を持つファイルの良い例が記載されています。とにかく、それはawk
とは何の関係もありませんが、datamash
はこのような場合に非常に役立ち、awk
と組み合わせて使用することもできると思います。それが誰かを助けることを願っています!