パターンの横の数字の標準偏差

パターンの横の数字の標準偏差

タグの多いファイルがあり、タグの横に次のような数字があります。

<Score>4
... other data
<Score>2
... other data
<Score>3

など...

grep を使用して 1 行で発生回数を取得します。

grep -c '<Score>' $1

awkを用いて小数の和を計算した。

awk 'sub(/<Score>/,""){y+=$0} END{print y}' $1}

次に、grepから得られた数で割って平均を求めます。

私が心配しているのは、<Score>の横にある各値の平均を求めて二乗し、それを加算する方法です。

平均は変数$ meanに保存されます。私が試したコードは次のとおりです。

awk 'sub(/<Score>/,""){y+=($0-$mean)^2} END{print y}' $1

ただし、ゼロを出力し続けます。これを変数に保存できる場合は、他のすべての変数を使用して標準偏差を計算できます。

答え1

以下は、利用可能ないくつかのユーティリティです。最初は、与えられた数値の平均を計算します(1行あたり1つの数値)。 2 番目は、1 番目を使用して、ファイル内の数値の標準偏差を計算します。


実行可能ファイルaverage:

#!/usr/bin/awk -f

/^[0-9.+-]/     { sum += $0; ++n }

END             { print sum / n }

スクリプトawkはファイルまたは標準入力から入力を読み取り、その中の数値の平均を計算します。 1行に1つの数字が必要です。


実行可能ファイルstdev:

#!/bin/sh

awk -v avg="$( ./average "$1" )" \
    '/^[0-9.+-]/ { sum += ($0 - avg)^2; ++n }
     END         { print sqrt(sum / (n - 1)) }' "$1"

このシェルスクリプトは最初に上記のaverageスクリプトを使用して、コマンドラインで提供されたファイルのデータ平均を計算します。番号はawk変数に割り当てられますavg。次に、スクリプトと同じ種類の数値検出を使用してaverage標準偏差を計算します。

このスクリプトは現在作成中なので、標準入力ではなくファイルのデータが必要です。


データに使用する1つの方法:

sed -n '/^<Score>/s///p' input.dat >output.dat

output.dat指定されたデータを使用して、次の内容で呼び出されるファイルを生成します。

4
2
3

stdevこのファイルには上記のスクリプトを使用してください。

$ ./stdev output.dat
1

私の知る限り、これは正しいです。


もちろん、awk再利用可能なツールを構築することなく、単一の呼び出しでこれを直接実行することもできます。

awk -F '>' '/^<Score>/ { v[++n] = $2; s += $2 }
            END { avg = s/n;
                  for (i=1; i<=n; ++i) {
                      std += (v[i] - avg)^2;
                  }
                  print sqrt(std / (n - 1));
                 }' input.dat

関連情報