命令行实用程序,用于在linux中打印数字统计信息

时间:2012-03-20 15:31:48

标签: linux command-line statistics

我经常发现自己的文件每行有一个数字。我最终在excel中导入它来查看中位数,标准差等等。

linux中是否有命令行实用程序来执行相同的操作?我通常需要找到平均值,中位数,最小值,最大值和标准偏差。

16 个答案:

答案 0 :(得分:52)

这对于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您将从终端传递表达式
  • x基本上是data.frame - 一张桌子。它是一个容纳多个向量/列数据的结构,如果您只是在单个向量中读取,这有点奇怪。这会对您可以使用的功能产生影响。
  • 某些功能(如summary())自然适应data.frames。如果x有多个字段,summary()会为每个字段提供上述描述性统计信息。
  • 但是sd()一次只能获取一个向量,这就是我为该命令索引x的原因(x[ , 1]返回x的第一列)。您可以使用apply(x, MARGIN = 2, FUN = sd)获取所有列的SD。

答案 1 :(得分:35)

使用“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

(免责声明:我写了这个工具:))

答案 2 :(得分:33)

对于平均值,中位数和&amp;您可以使用标准偏差awk。这通常比R解决方案更快。例如,以下将打印平均值:

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

NR是记录数的awk变量,$1表示该行的第一个(空格分隔的)参数($0将是整个line,也可以在这里工作,但原则上安全性会降低,尽管对于计算它可能只需要第一个参数)而END意味着在处理完整个文件后将执行以下命令(也可以在a语句中将0初始化为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
}

可以直接在此脚本中添加min / max,但管道sort&amp; head / tail

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

答案 3 :(得分:19)

Y.a。可用于计算ASCII模式下的统计和视图分布的工具是 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

答案 4 :(得分:14)

是的,它被称为perl
这是简洁的单行:

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

答案 5 :(得分:11)

<强>平均数:

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

答案 6 :(得分:8)

data_hacks is a Python command-line utility for basic statistics.

该页面的第一个示例产生了所需的结果:

$ 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]: *

答案 7 :(得分:7)

以防万一,datastat是一个简单的程序,用于Linux计算命令行的简单统计。例如,

cat file.dat | datastat

将输出file.dat每列的所有行的平均值。如果您需要知道标准差,最小值,最大值,则可以分别添加--dev--min--max选项。

datastat可以根据一个或多个“key”列的值聚合行。例如,

cat file.dat | datastat -k 1
对于在第一列(“键”)上找到的每个不同值,

将生成在键上具有相同值的所有行之间聚合的所有其他列值的平均值。您可以使用更多列作为关键字段(例如,-k 1-3,-k 2,4等...)。

它是用C ++编写的,运行速度快,内存占用少,可以使用其他工具很好地管理,例如cutgrepsedsortawk等。

答案 8 :(得分:7)

您也可以考虑使用clistats。它是一个高度可配置的命令行界面工具,用于计算分隔输入数字流的统计信息。

I / O选项

  • 输入数据可以来自文件,标准输入或管道
  • 可以将输出写入文件,标准输出或管道
  • 输出使用以“#”开头的标题以启用到gnuplot的管道

解析选项

  • 信号,文件结束或基于空行的检测以停止处理
  • 可以设置评论和分隔符字符
  • 可以从处理中过滤掉列
  • 可以根据数字约束
  • 过滤掉行
  • 可以根据字符串约束
  • 过滤掉行
  • 可以跳过初始标题行
  • 可以处理固定数量的行
  • 可以忽略重复的分隔符
  • 可以将行重新整理为列
  • 严格执行只处理相同尺寸的行
  • 包含列标题的行可用于标题输出统计信息

统计选项

  • 摘要统计(计数,最小值,平均值,最大值,标准差)
  • 协方差
  • 相关性
  • 最小二乘偏移
  • 最小二乘斜率
  • 直方图
  • 过滤后的原始数据

注意:我是作者。

答案 9 :(得分:6)

我发现自己想要在shell管道中执行此操作,并且为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选项"Make(s) R run as quietly as possible...It implies --quiet and --no-save." -e选项告诉R将以下字符串视为R代码。第一个语句从标准输入读取,并存储在名为“x”的变量中读取的内容。 scan函数的quiet=TRUE选项会禁止写一行,说明有多少项被读取。第二个语句将summary函数应用于x,它产生输出。

答案 10 :(得分:4)

又一个工具: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预先包装的第一个工具)

答案 11 :(得分:3)

#!/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;

答案 12 :(得分:3)

还有simple-r,它几乎可以完成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!

答案 13 :(得分:2)

另一个工具:tsv-summarize,来自eBay's tsv utilities。支持最小值,最大值,平均值,中位数,标准差。适用于大型数据集。例如:

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

免责声明:我是作者。

答案 14 :(得分:1)

使用xsv

function alert(){
  return eventChannel(emitter => {
    Alert.alert(
      'User',
      'User request ok!',
      [
        {text: 'OK', onPress: () => emitter('OK')},
      ],
      { cancelable: false }
    )
  })
}

function* saga(){
  yield takeEvery(types.REQUEST_OK, function*(){
    const channel = yield alert()
    // while(true){
    const button = yield take(channel)
    yield put({type: types.NAVIGATION_BACK})
    // }
  });
}

答案 15 :(得分:0)

此外,自写的https://bugs.python.org/issue42114(与'scut'捆绑在一起)是一个perl util来实现的。在STDIN上输入了数字流,它试图拒绝非数字并发出以下消息:

@if (Model != null) { 
    <a onclick="get('@Url.Action("DemoAction", "DemoController")', @Model.Id)" ></a>
}

它还可以对输入流进行许多转换,并且仅在发出要求时才发出未经修饰的值;即'stats --mean'将以未标记的浮点数返回平均值。