我经常发现自己的文件每行有一个数字。我最终在excel中导入它来查看中位数,标准差等等。
linux中是否有命令行实用程序来执行相同的操作?我通常需要找到平均值,中位数,最小值,最大值和标准偏差。
答案 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 -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 ++编写的,运行速度快,内存占用少,可以使用其他工具很好地管理,例如cut
,grep
,sed
,sort
, awk
等。
答案 8 :(得分:7)
您也可以考虑使用clistats。它是一个高度可配置的命令行界面工具,用于计算分隔输入数字流的统计信息。
注意:我是作者。
答案 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'将以未标记的浮点数返回平均值。