最初の列が同じ平均行

最初の列が同じ平均行

2つの列を含むファイルがある場合:

Id  ht
510 69
510 67
510 65
510 62
510 59
601 29
601 26
601 21
601 20

同じIDを持つすべての行を平均高さの行にマージする方法が必要です。この例では、(69 + 67 + 65 + 62 + 59)/ 5 = 64および(29 + 26 + 21 + 20)/ 4 = 24なので、出力は次のようになります。

Id  Avg.ht
 510 64
 601 24

sed/awk/perlを使ってこれを行うにはどうすればよいですか?

答え1

awkを使う:

入力ファイル

$ cat FILE
Id  ht
510 69
510 67
510 65
510 62
510 59
601 29
601 26
601 21
601 20

シェルからawk:

$ awk '
    NR>1{
        arr[$1]   += $2
        count[$1] += 1
    }
    END{
        for (a in arr) {
            print "id avg " a " = " arr[a] / count[a]
        }
    }
' FILE

または、シェルでPerlを使用してください。

$ perl -lane '
    END {
        foreach my $key (keys(%hash)) {
            print "id avg $key = " . $hash{$key} / $count{$key};
        }
    }
    if ($. > 1) {
        $hash{$F[0]}  += $F[1];
        $count{$F[0]} += 1;
    }
' FILE

出力は次のとおりです

id avg 601 = 24
id avg 510 = 64.4

最後のジョークはPerlの暗く難読化された一行のジョークです =)

perl -lane'END{for(keys(%h)){print"$_:".$h{$_}/$c{$_}}}($.>1)&&do{$h{$F[0]}+=$F[1];$c{$F[0]}++}' FILE

答え2

#!/usr/bin/perl
use strict;
use warnings;

my %sum_so_far;
my %count_so_far;
while ( <> ) {
    # Skip lines that don't start with a digit
    next if m/^[^\d]/;

    # Accumulate the sum and the count
    my @line = split();
    $sum_so_far{$line[0]}   += $line[1];
    $count_so_far{$line[0]} += 1;
}

# Dump the output
print "Id Avg.ht\n";
foreach my $id ( keys %count_so_far ) {
    my $avg = $sum_so_far{$id}/$count_so_far{$id};
    print " $id $avg\n";
}

出力:

ire@localhost$ perl make_average.pl input.txt 
Id Avg.ht
 510 64.4
 601 24

出力例が正しくありません。そのIDのすべての値が59以上の場合、平均52は得られません。

また、列の1つにl数字で偽装された文字があります1

答え3

そしてgnu datamash:

datamash -H -s -g 1 mean 2 <file
GroupBy(ID) 平均()
510 64.4
601 24

sヘッダーを維持しながら、ソートおよびグループ化する最初のフィールドに基づいて2番目のフィールド値を計算します。フィールドが単一のタブ文字で区切られていると仮定します。複数のスペースで区切ったり、異なるフィールド区切り文字(スペース、カンマなど)を定義したりする場合に使用されます。入力をソートする必要があるため、出力はグループ化列に基づいてソートされます。g12meanH-W, --whitespace-t, --field-separator=datamash

答え4

ここで行われたことを確認してください。http://www.sugihartono.com/programming/group-by-count-and-sorting-using-perl-script/

最も難しいのは、「グループ別」の操作を実行することです。リンカスクリプトはこれを達成するためにハッシュを使用します。

そのリンクでは合計を計算しますが、平均を求めても大きな違いはありません。

関連情報