1列と2列から最大値と最小値を抽出する方法

1列と2列から最大値と最小値を抽出する方法

愛する皆さん、私には一つあります。大きいデータファイルは次のように言えます。ファイル.dat、2つの列が含まれています。

たとえば、file.dat(複数行を表示)

    0.0000  -23.4334
    0.0289  -23.4760
    0.0578  -23.5187
    0.0867  -23.5616
    0.1157  -23.6045
    0.1446  -23.6473
    0.1735  -23.6900
    0.2024  -23.7324
    0.2313  -23.7745
    0.2602  -23.8162
    0.2892  -23.8574
    0.3181  -23.8980
    0.3470  -23.9379
    0.3759  -23.9772
    0.4048  -24.0156
    0.4337  -24.0532
    0.4627  -24.0898
    0.4916  -24.1254
note: data file has a blank line at the end of the file

期待されるパフォーマンス

列(列1など)で最大値と最小値を検索または抽出したいです。

max - 0.4916
min - 0.0000

2列と同じ

max - -23.4334
min - -24.1254

不完全な年(2列には適用されません)

列1の場合

awk 'BEGIN{min=9}{for(i=1;i<=1;i++){min=(min<$i)?min:$i}print min;exit}' file.dat 
0.0000
cat file.dat | awk '{if ($1 > max) max=$1}END{print max}'
0.4916

2列の場合

awk 'BEGIN{min=9}{for(i=2;i<=2;i++){min=(min<$i)?min:$i}print min;exit}' file.dat
-23.4334

cat file.dat | awk '{if ($2 > max) max=$2}END{print max}'
**no output showing**

質問

2列の最小値と最大値を見つけるのに役立ちます。 注:データファイルの末尾に空白行があります。

ベストアンサー1

コードの問題、

awk 'BEGIN{min=9}{for(i=2;i<=2;i++){min=(min<$i)?min:$i}print min;exit}' file.dat

...exit入力の最初の行を処理した直後に実行する操作です。中間ブロックをトリガーする必要があります。すべてワイヤー。その後、ENDブロックで見つかった値を印刷できます。他のコードスニペットでこれを行うことができます。

awk '{if ($1 > max) max=$1}END{print max}'

もう1つの問題は、min初期化に魔法の数字を使用することです(引用した最初のコードでは9、2番目のコードでは0、明示的に初期化されていない変数が計算に使用される場合、その値は0です)。このマジックナンバーが実際のデータの数値範囲を超えると、計算された最小値および/または最大値が間違ってしまいます。最小値と最大値の両方をデータで見つかった値に初期化するのが最善です。

追跡し続ける...両方最小値と最大値には2つの変数が必要であり、ファイル内の各データ行に対してこれら2つの変数を確認して更新する必要があることを確認する必要があります。

awk配列がサポートされているため、合計に配列を使用するのはmin自然ですmax(1列あたり1つの配列要素)。これが私が以下のコードでやっていることです。


必要な数の列に一般化します。

NF == 0 {
        # Skip any line that does not have data
        next
}

!initialized {
        # Initialize the max and min for each column from the
        # data on the first line of input that has data.
        # Then immediately skip to next line.

        nf = NF

        for (i = 1; i <= nf; ++i)
                max[i] = min[i] = $i

        initialized = 1
        next
}

{
        # Loop over the columns to see if the max and/or min
        # values need updating.

        for (i = 1; i <= nf; ++i) {
                if (max[i] < $i) max[i] = $i
                if (min[i] > $i) min[i] = $i
        }
}

END {
        # Output max and min values for each column.

        for (i = 1; i <= nf; ++i)
                printf("Column %d: min=%s, max=%s\n", i, min[i], max[i])
}

このスクリプトと質問のデータを考慮すると、次のようになります。

$ awk -f script.awk file
Column 1: min=0.0000, max=0.4916
Column 2: min=-24.1254, max=-23.4334

最初のブロック(すべての行で実行されます)の条件NF == 0は、空の行をスキップすることです。このテストは、「この行にデータフィールド(列)がゼロの場合」を意味します。この変数はinitialized最初から0です(論理的に間違った)ですが、1に設定されています(論理的には本物)データの最初の行を読んだ後。

変数は、初期化して値を指定する行で(フィールド数)にnf初期化されます。NFこれにより、最後の行のフィールドがゼロであってもブロックの出力は正常に機能します。minmaxEND

おすすめ記事