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


74

我经常发现自己的文件每行有一个数字。我最终将其导入excel以查看诸如中位数,标准差等内容。

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





提出这个问题的人们也可能对jpCLI实用工具感兴趣。
马特·帕克

Answers:


58

使用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标志squelches的r启动许可和帮助输出
  • -e标志告诉R您将要从终端传递一个表达式
  • xdata.frame基本上是一张桌子。它是一个可容纳多个向量/数据列的结构,如果您仅读取单个向量,则该结构会有些特殊。这会影响您可以使用哪些功能。
  • 有些功能,例如summary(),自然可以容纳data.frames。如果x有多个字段,summary()则将为每个字段提供上述描述性统计信息。
  • 但是sd()一次只能取一个向量,这就是为什么我x为该命令建立索引(x[ , 1]返回的第一列x)的原因。您可以apply(x, MARGIN = 2, FUN = sd)用来获取所有列的SD。

谢谢。我已经,使用R自从开始,我认为这是一个伟大的工具来了解数据
MK。

4
要保存有关如何在Ubuntu上获得R的额外搜索:sudo apt-get install r-base
E-rich

1
R将来可能会更好地使用它,但是我猜测这是一个巨大的库安装,因此我考虑过st在下面安装表格。与此评论无关,但我brew install R在MacBook Pro 2015年中10.12.5 2.5GHz i7 16GB(带有Chrome,Atom和其他应用程序)上打开仅一个小时。它的大部分用于用Xcode CLT O_o构建一些gcc jit补丁,但是现在我很高兴地使用了部分答案:)
Pysis

这是一篇有关使用bash工具进行常规数据处理的博客文章,可能会引起发现此问题的人们的兴趣。
马特·帕克

45

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

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


1
有关新手安装的任何信息
NeDark 2015年

3
如果您使用自制软件,则安装过程很简单brew install st
杰森·阿克森

1
当心st可能还提到了simple terminal
Skippy le Grand Gourou

36

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

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

NRawk记录数量的变量,$1表示该行的第一个(以空格分隔)参数($0将是整行,在此处也可以使用,但原则上不太安全,尽管对于计算而言,它可能只是无论如何都采用第一个参数),END表示在处理了整个文件之后(也可以在语句中将其初始化a为)之后,将执行以下命令。0BEGIN{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
}

向此脚本添加最小值/最大值很简单,但是通过管道传递管道sorthead/ tail :

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

22

ministat是另一个可用于以ASCII模式计算统计信息和视图分布的工具。它是FreeBSD的工具,但也打包用于Debian / Ubuntu等流行的Linux发行版。或者,您可以简单地从源代码下载并构建它-它仅需要C编译器和C标准库。

用法示例:

$ 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

17

是的,它叫做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

20
我敢肯定,这是行得通的,但只用一行就可以使我的眼睛流血。为什么不创建脚本,而不是创建一个残酷的行为?
奥利弗·查尔斯沃思

18
我非常确定“功能语言”!=“将所有内容尽可能简洁地写在一行上”。
奥利弗·查尔斯沃思

10
仅因为您可以一行完成某件事并不意味着您应该
Mike Monkiewicz

8
Oneliners绝对不适合阅读。但是它们很棒,只需将其复制粘贴到我的腻子中,并从apache日志中获取某些数字的统计信息即可... So bua roxx
Vajk Hermecz 2014年

3
命令行(至少是bash)也支持多行字符串。只需在文字内部使用换行符即可。
圣保罗Ebermann

14

意思:

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

2
做得很好-并且使用了每个Linux发行版上的工具。
rbellamy

1
@rbellamy-谢谢!而且不只是Linux的-我管理的FreeBSD系统,其中的区别awkgawk重要(因为普通旧的AWK在BSD不包括asort())。
ghoti


8

以防万一,这里有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 ++编写,运行速度快和小内存占用,可以用其他工具,如管道很好cutgrepsedsortawk等。



8

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

7

您可能还考虑使用气候调节器。这是一个高度可配置的命令行界面工具,用于计算定界输入数字流的统计信息。

I / O选项

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

解析选项

  • 基于信号,文件结尾或空白行的检测来停止处理
  • 可以设置注释和分隔符
  • 可以从处理中过滤掉列
  • 可以根据数值约束将行从处理中过滤掉
  • 可以基于字符串约束将行从处理中过滤掉
  • 初始标题行可以跳过
  • 固定数量的行可以处理
  • 重复的分隔符可以忽略
  • 行可以重塑为列
  • 严格执行仅处理相同大小的行
  • 包含列标题的行可用于标题输出统计信息

统计选项

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

注意:我是作者。


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选项“使(S)R运行尽可能平静......这意味着--quiet和--no保存。” -e选项告诉R将以下字符串视为R代码。第一条语句从standard in读取,并将读取的内容存储在名为“ x”的变量中。该函数的quiet=TRUE选项scan禁止写一行,该行表示已读取多少项。第二条语句将该summary函数应用于x,产生输出。


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;

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!


有趣的是,它是R的Perl包装器。R不是编程语言!> :-)
Ciro Santilli郝海东冠状病六四事件法轮功

2

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

1
安装后brew发现有很多依赖项。此功能相当“繁重”。
Alex Moore-Niemi

所以不要使用brew吗?github.com/BurntSushi/xsv/releases已经为macOS预编译了二进制文件,因此应该没有理由安装完整的rust工具链或brew所做的任何事情。
锤击

2

另一个工具:tsv-summarize,来自eBay的tsv实用程序。最小,最大,平均值,中位数,标准偏差均受支持。适用于大型数据集。例:

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

免责声明:我是作者。


0

此外,perl util自写统计信息(与“ scut”捆绑在一起)可以做到这一点。在STDIN上输入了数字流,它尝试拒绝非数字并发出以下内容:

$ ls -lR | scut -f=4 | stats
Sum       3.10271e+07
Number    452
Mean      68643.9
Median    4469.5
Mode      4096
NModes    6
Min       2
Max       1.01171e+07
Range     1.01171e+07
Variance  3.03828e+11
Std_Dev   551206
SEM       25926.6
95% Conf  17827.9 to 119460
          (for a normal distribution - see skew)
Skew      15.4631
          (skew = 0 for a symmetric dist)
Std_Skew  134.212
Kurtosis  258.477
          (K=3 for a normal dist)

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

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.