development

Linux에서 숫자 통계를 인쇄하는 명령 줄 유틸리티

big-blog 2020. 11. 22. 20:01
반응형

Linux에서 숫자 통계를 인쇄하는 명령 줄 유틸리티


나는 종종 한 줄에 하나의 숫자가있는 파일을 발견합니다. 중간 값, 표준 편차 등을보기 위해 Excel로 가져옵니다.

Linux에 동일한 작업을 수행하는 명령 줄 유틸리티가 있습니까? 일반적으로 평균, 중앙값, 최소값, 최대 값 및 표준 편차를 찾아야합니다.


R을 사용하는 것은 매우 쉽습니다. 다음과 같은 파일의 경우 :

1
2
3
4
5
6
7
8
9
10

이것을 사용하십시오 :

R -q -e "x <- read.csv('nums.txt', header = F); summary(x); sd(x[ , 1])"

이것을 얻으려면 :

       V1       
 Min.   : 1.00  
 1st Qu.: 3.25  
 Median : 5.50  
 Mean   : 5.50  
 3rd Qu.: 7.75  
 Max.   :10.00  
[1] 3.02765
  • -q플래그는 R의 시작 라이선스와 도움말 출력을 억제합니다.
  • -e플래그를 사용하면 터미널에서 식을 전달됩니다 R을 알려줍니다
  • xA는 data.frame기본적으로 테이블 -. 이는 여러 벡터 / 데이터 열을 수용하는 구조로, 단일 벡터에서 읽는 경우 약간 특이합니다. 이것은 사용할 수있는 기능에 영향을 미칩니다.
  • 과 같은 일부 기능은 summary()자연스럽게 data.frames. x필드가 여러 개인 경우 summary()각각에 대해 위의 설명 통계를 제공합니다.
  • 그러나 sd()한 번에 하나의 벡터 만 사용할 수 있으므로 x해당 명령에 대해 색인 생성 합니다 ( x[ , 1]의 첫 번째 열을 반환 함 x). apply(x, MARGIN = 2, FUN = sd)모든 열에 대한 SD를 가져 오는 데 사용할 수 있습니다 .

"st"사용 ( https://github.com/nferraz/st )

$ st numbers.txt
N    min   max   sum   mean  stddev
10   1     10    55    5.5   3.02765

또는:

$ st numbers.txt --transpose
N      10
min    1
max    10
sum    55
mean   5.5
stddev 3.02765

(면책 조항 :이 도구를 작성했습니다 :))


평균, 중앙값 및 표준 편차의 경우 awk. 이것은 일반적으로 R솔루션 보다 빠릅니다 . 예를 들어 다음은 평균을 인쇄합니다.

awk '{a+=$1} END{print a/NR}' myfile

( NRawk레코드 수에 대한 변수 $1이며, 줄의 첫 번째 (공백으로 구분 된) 인수를 의미합니다 ( $0전체 줄이 될 수 있으며 여기서도 작동하지만 원칙적으로 덜 안전하지만 계산을 위해서는 아마도 어쨌든 첫 번째 인수를)하고 END다음 명령이 (하나는 초기화 수도 전체 파일을 처리 한 후에 실행된다는 것을 의미 a0A의 BEGIN{a=0}문)).

다음은 awk더 자세한 통계를 제공 하는 간단한 스크립트입니다 (CSV 파일을 입력으로 사용하거나 변경하지 않으면 변경 FS).

#!/usr/bin/awk -f

BEGIN {
    FS=",";
}
{
   a += $1;
   b[++i] = $1;
}
END {
    m = a/NR; # mean
    for (i in b)
    {
        d += (b[i]-m)^2;
        e += (b[i]-m)^3;
        f += (b[i]-m)^4;
    }
    va = d/NR; # variance
    sd = sqrt(va); # standard deviation
    sk = (e/NR)/sd^3; # skewness
    ku = (f/NR)/sd^4-3; # standardized kurtosis
    print "N,sum,mean,variance,std,SEM,skewness,kurtosis"
    print NR "," a "," m "," va "," sd "," sd/sqrt(NR) "," sk "," ku
}

이 스크립트에 최소 / 최대를 추가하는 것은 간단하지만 파이프 sort& head/ 만큼 쉽습니다 tail .

sort -n myfile | head -n1
sort -n myfile | tail -n1

ASCII 모드에서 통계 계산 및보기 분포에 사용할 수있는 Ya 도구는 ministat 입니다. FreeBSD의 도구이지만 Debian / Ubuntu와 같은 널리 사용되는 Linux 배포판 용으로도 패키징되었습니다.

사용 예 :

$ cat test.log 
Handled 1000000 packets.Time elapsed: 7.575278
Handled 1000000 packets.Time elapsed: 7.569267
Handled 1000000 packets.Time elapsed: 7.540344
Handled 1000000 packets.Time elapsed: 7.547680
Handled 1000000 packets.Time elapsed: 7.692373
Handled 1000000 packets.Time elapsed: 7.390200
Handled 1000000 packets.Time elapsed: 7.391308
Handled 1000000 packets.Time elapsed: 7.388075

$ cat test.log| awk '{print $5}' | ministat -w 74
x <stdin>
+--------------------------------------------------------------------------+
| x                                                                        |
|xx                                   xx    x x                           x|
|   |__________________________A_______M_________________|                 |
+--------------------------------------------------------------------------+
    N           Min           Max        Median           Avg        Stddev
x   8      7.388075      7.692373       7.54768     7.5118156    0.11126122

네, 그것은 펄이라고 불리며
여기에 간결한 한 줄짜리가 있습니다.

perl -e 'use List::Util qw(max min sum); @a=();while(<>){$sqsum+=$_*$_; push(@a,$_)}; $n=@a;$s=sum(@a);$a=$s/@a;$m=max(@a);$mm=min(@a);$std=sqrt($sqsum/$n-($s/$n)*($s/$n));$mid=int @a/2;@srtd=sort @a;if(@a%2){$med=$srtd[$mid];}else{$med=($srtd[$mid-1]+$srtd[$mid])/2;};print "records:$n\nsum:$s\navg:$a\nstd:$std\nmed:$med\max:$m\min:$mm";'

$ cat tt
1
3
4
5
6.5
7.
2
3
4

그리고 명령

cat tt | perl -e 'use List::Util qw(max min sum); @a=();while(<>){$sqsum+=$_*$_; push(@a,$_)}; $n=@a;$s=sum(@a);$a=$s/@a;$m=max(@a);$mm=min(@a);$std=sqrt($sqsum/$n-($s/$n)*($s/$n));$mid=int @a/2;@srtd=sort @a;if(@a%2){$med=$srtd[$mid];}else{$med=($srtd[$mid-1]+$srtd[$mid])/2;};print "records:$n\nsum:$s\navg:$a\nstd:$std\nmed:$med\max:$m\min:$mm";'
records:9
sum:35.5
avg:3.94444444444444
std:1.86256162380447
med:4
max:7.
min:1

평균:

awk '{sum += $1} END {print "mean = " sum/NR}' filename

중앙값:

gawk -v max=128 '

    function median(c,v,    j) { 
       asort(v,j) 
       if (c % 2) return j[(c+1)/2]
       else return (j[c/2+1]+j[c/2])/2.0
    }

    { 
       count++
       values[count]=$1
       if (count >= max) { 
         print  median(count,values); count=0
       } 
    } 

    END { 
       print  "median = " median(count,values)
    }
    ' filename

방법:

awk '{c[$1]++} END {for (i in count) {if (c[i]>max) {max=i}} print "mode = " max}' filename

이 모드 계산에는 짝수의 샘플이 필요하지만 어떻게 작동하는지 알 수 있습니다.

표준 편차:

awk '{sum+=$1; sumsq+=$1*$1} END {print "stdev = " sqrt(sumsq/NR - (sum/NR)**2)}' filename

data_hacks 기본 통계를위한 Python 명령 줄 유틸리티입니다.

해당 페이지의 첫 번째 예는 원하는 결과를 생성합니다.

$ cat /tmp/data | histogram.py
# NumSamples = 29; Max = 10.00; Min = 1.00
# Mean = 4.379310; Variance = 5.131986; SD = 2.265389
# each * represents a count of 1
    1.0000 -     1.9000 [     1]: *
    1.9000 -     2.8000 [     5]: *****
    2.8000 -     3.7000 [     8]: ********
    3.7000 -     4.6000 [     3]: ***
    4.6000 -     5.5000 [     4]: ****
    5.5000 -     6.4000 [     2]: **
    6.4000 -     7.3000 [     3]: ***
    7.3000 -     8.2000 [     1]: *
    8.2000 -     9.1000 [     1]: *
    9.1000 -    10.0000 [     1]: *

혹시라도 datastat명령 줄에서 간단한 통계를 계산하는 Linux 용 간단한 프로그램이 있습니다. 예를 들면

cat file.dat | datastat

file.dat의 각 열에 대한 모든 행의 평균 값을 출력합니다. 표준 편차 (최소, 최대)를 알아야하는 경우 --dev, --min--max옵션을 각각 추가 할 수 있습니다 .

datastat하나 이상의 "키"열 값을 기반으로 행을 집계 할 수 있습니다. 예를 들면

cat file.dat | datastat -k 1

첫 번째 열 ( "키")에서 발견 된 각 다른 값에 대해 키에서 동일한 값을 가진 모든 행에서 집계 된 다른 모든 열 값의 평균을 생성합니다. 더 많은 열을 키 필드로 사용할 수 있습니다 (예 : -k 1-3, -k 2,4 등).

그것은 C로 작성 ++, 빠르고 작은 메모리 직업으로 실행하고, 같은 다른 도구를 잘 파이프 할 수있다 cut, grep, sed, sort, awk


clistats 사용을 고려할 수도 있습니다 . 구분 된 입력 숫자의 스트림에 대한 통계를 계산하는 고도로 구성 가능한 명령 줄 인터페이스 도구입니다.

I / O 옵션

  • 입력 데이터는 파일, 표준 입력 또는 파이프에서 가져올 수 있습니다.
  • 출력은 파일, 표준 출력 또는 파이프에 기록 될 수 있습니다.
  • 출력은 "#"로 시작하는 헤더를 사용하여 gnuplot에 대한 파이프를 활성화합니다.

구문 분석 옵션

  • 처리 중지를위한 신호, 파일 끝 또는 빈 줄 기반 감지
  • 주석 및 구분 문자 설정 가능
  • 처리에서 열을 필터링 할 수 있습니다.
  • 숫자 제약에 따라 처리에서 행을 필터링 할 수 있습니다.
  • 문자열 제약 조건에 따라 처리에서 행을 필터링 할 수 있습니다.
  • 초기 헤더 행을 건너 뛸 수 있음
  • 고정 된 수의 행을 처리 할 수 ​​있습니다.
  • 중복 구분 기호는 무시할 수 있습니다.
  • 행을 열로 재구성 할 수 있습니다.
  • 동일한 크기의 행만 처리되도록 엄격히 시행
  • 열 제목을 포함하는 행을 사용하여 출력 통계의 제목을 지정할 수 있습니다.

통계 옵션

  • 요약 통계 (개수, 최소값, 평균, 최대 값, 표준 편차)
  • 공분산
  • 상관 관계
  • 최소 제곱 오프셋
  • 최소 제곱 기울기
  • 히스토그램
  • 필터링 후 원시 데이터

참고 : 저는 저자입니다.


또 다른 도구 : https://www.gnu.org/software/datamash/

# Example: calculate the sum and mean of values 1 to 10:
$ seq 10 | datamash sum 1 mean 1
55 5.5

더 일반적으로 패키징 될 수 있습니다 (적어도 nix 용으로 미리 패키징 된 첫 번째 도구)


쉘 파이프 라인에서이 작업을 수행하고 싶었고 R에 대한 모든 올바른 인수를 얻는 데 시간이 걸렸습니다. 내가 생각 해낸 것은 다음과 같습니다.

seq 10 | R --slave -e 'x <- scan(file="stdin",quiet=TRUE); summary(x)' Min. 1st Qu. Median Mean 3rd Qu. Max. 1.00 3.25 5.50 5.50 7.75 10.00

--slave옵션 "조용히 가능한 한 메이크업 (들) R 실행 ... 그것은 --quiet와 --no-저장 의미한다." -e옵션은 R에게 다음 문자열을 R 코드로 처리하도록 지시합니다. 첫 번째 문은 표준 입력에서 읽고 읽은 내용을 "x"라는 변수에 저장합니다. 함수에 대한 quiet=TRUE옵션 scan은 읽은 항목 수를 나타내는 행 쓰기를 억제합니다. 두 번째 문은에 summary함수를 적용 x하여 출력을 생성합니다.


#!/usr/bin/perl
#
# stdev - figure N, min, max, median, mode, mean, & std deviation
#
# pull out all the real numbers in the input
# stream and run standard calculations on them.
# they may be intermixed with other test, need
# not be on the same or different lines, and 
# can be in scientific notion (avagadro=6.02e23).
# they also admit a leading + or -.
#
# Tom Christiansen
# tchrist@perl.com

use strict;
use warnings;

use List::Util qw< min max >;

#
my $number_rx = qr{

  # leading sign, positive or negative
    (?: [+-] ? )

  # mantissa
    (?= [0123456789.] )
    (?: 
        # "N" or "N." or "N.N"
        (?:
            (?: [0123456789] +     )
            (?:
                (?: [.] )
                (?: [0123456789] * )
            ) ?
      |
        # ".N", no leading digits
            (?:
                (?: [.] )
                (?: [0123456789] + )
            ) 
        )
    )

  # abscissa
    (?:
        (?: [Ee] )
        (?:
            (?: [+-] ? )
            (?: [0123456789] + )
        )
        |
    )
}x;

my $n = 0;
my $sum = 0;
my @values = ();

my %seen = ();

while (<>) {
    while (/($number_rx)/g) {
        $n++;
        my $num = 0 + $1;  # 0+ is so numbers in alternate form count as same
        $sum += $num;
        push @values, $num;
        $seen{$num}++;
    } 
} 

die "no values" if $n == 0;

my $mean = $sum / $n;

my $sqsum = 0;
for (@values) {
    $sqsum += ( $_ ** 2 );
} 
$sqsum /= $n;
$sqsum -= ( $mean ** 2 );
my $stdev = sqrt($sqsum);

my $max_seen_count = max values %seen;
my @modes = grep { $seen{$_} == $max_seen_count } keys %seen;

my $mode = @modes == 1 
            ? $modes[0] 
            : "(" . join(", ", @modes) . ")";
$mode .= ' @ ' . $max_seen_count;

my $median;
my $mid = int @values/2;
if (@values % 2) {
    $median = $values[ $mid ];
} else {
    $median = ($values[$mid-1] + $values[$mid])/2;
} 

my $min = min @values;
my $max = max @values;

printf "n is %d, min is %g, max is %d\n", $n, $min, $max;
printf "mode is %s, median is %g, mean is %g, stdev is %g\n", 
    $mode, $median, $mean, $stdev;

R이 할 수있는 거의 모든 것을 할 수있는 simple-r도 있지만 키 입력은 더 적습니다.

https://code.google.com/p/simple-r/

기본 기술 통계량을 계산하려면 다음 중 하나를 입력해야합니다.

r summary file.txt
r summary - < file.txt
cat file.txt | r summary -

평균, 중앙값, 최소, 최대 및 표준 편차 각각에 대해 코드는 다음과 같습니다.

seq 1 100 | r mean - 
seq 1 100 | r median -
seq 1 100 | r min -
seq 1 100 | r max -
seq 1 100 | r sd -

간단한 R을 얻지 못합니다!


또 다른 도구 : tsv-summarize, eBay의 tsv 유틸리티에서 . 최소, 최대, 평균, 중앙값, 표준 편차가 모두 지원됩니다. 대용량 데이터 세트 용입니다. 예:

$ seq 10 | tsv-summarize --min 1 --max 1 --median 1 --stdev 1
1    10    5.5    3.0276503541

면책 조항 : 저는 저자입니다.


xsv 사용 :

$ echo '3 1 4 1 5 9 2 6 5 3 5 9' |tr ' ' '\n' > numbers-one-per-line.csv

$ xsv stats -n < numbers-one-per-line.csv 
field,type,sum,min,max,min_length,max_length,mean,stddev
0,Integer,53,1,9,1,1,4.416666666666667,2.5644470922381863

# mode/median/cardinality not shown by default since it requires storing full file in memory:
$ xsv stats -n --everything < numbers-one-per-line.csv | xsv table
field  type     sum  min  max  min_length  max_length  mean               stddev              median  mode  cardinality
0      Integer  53   1    9    1           1           4.416666666666667  2.5644470922381863  4.5     5     7

참고 URL : https://stackoverflow.com/questions/9789806/command-line-utility-to-print-statistics-of-numbers-in-linux

반응형