첫 번째 열이 동일한 평균 행

첫 번째 열이 동일한 평균 행

두 개의 열이 포함된 파일이 있는 경우:

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를 얻을 수 없습니다.

또한 열 중 하나에 l숫자로 위장한 문자가 있습니다 1.

답변3

그리고gnu datamash:

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

s헤더를 유지하면서 정렬 및 그룹화할 첫 번째 필드를 기준으로 두 번째 필드 값을 계산합니다 . 필드가 단일 탭 문자로 구분되어 있다고 가정합니다. 여러 공백으로 구분되거나 다른 필드 구분 기호(공백, 쉼표 등)를 정의하는 경우 사용됩니다. 입력을 정렬해야 하므로 출력은 그룹화 열을 기준으로 정렬됩니다.g12meanH-W, --whitespace-t, --field-separator=datamash

답변4

여기에서 수행된 작업을 확인하세요.http://www.sugihartono.com/programming/group-by-count-and-sorting-using-perl-script/

가장 어려운 부분은 "그룹별" 작업을 수행하는 것입니다. 링커 스크립트는 이를 달성하기 위해 해시를 사용합니다.

해당 링크에서는 합계를 계산하지만 평균을 구해도 큰 차이가 없습니다.

관련 정보