Bash 使用bc或其他标准实用程序的任意数目的标准偏差
是否有一些技巧可以让我们使用bc(或其他标准工具)返回任意数量数字的标准偏差?为了方便起见,假设数字以以下方式存储在Bash变量中:Bash 使用bc或其他标准实用程序的任意数目的标准偏差,bash,variables,standard-deviation,awk,perl,Bash,Variables,Standard Deviation,Awk,Perl,是否有一些技巧可以让我们使用bc(或其他标准工具)返回任意数量数字的标准偏差?为了方便起见,假设数字以以下方式存储在Bash变量中: myNumbers="0.556 1.456 45.111 7.812 5.001" 因此,我要寻找的答案将是以下形式: standardDeviation="$(echo "${myNumbers}" | <insert magic here>)" standardDeviation=“$(echo“${myNumbers}”|)” 使用: 使用
myNumbers="0.556
1.456
45.111
7.812
5.001"
因此,我要寻找的答案将是以下形式:
standardDeviation="$(echo "${myNumbers}" | <insert magic here>)"
standardDeviation=“$(echo“${myNumbers}”|)”
使用:
使用:
输出
或者使用GNU倍频程(它可以比简单的std多得多):
输出
18.742
总体标准偏差:
jq-s'(add/length)作为$a | map(pow(.-$a;2))| add/length | sqrt'
ruby-e'a=readlines.map(&:to_f);放置(a.map{| x |(x-a.reduce(:+)/a.length)**2}.reduce(:+)/a.length)**0.5'
jq-s'(地图(.*)|添加/长度)-pow(添加/长度;2)| sqrt'
awk“{x+=$0;y+=$0^2}结束{print sqrt(y/NR-(x/NR)^2)}”
在awk
中,^
在POSIX中,但**
不在POSIX中**
受gawk
和nawk
支持,但不受mawk
支持
样本标准偏差(前两个命令与上面的前两个命令相同,但length
已替换为length-1
):
jq-s'(添加/长度)为$a | map(pow(.-$a;2))|添加/(长度-1)| sqrt'
ruby-e'a=readlines.map(&:to_f);放置(a.map{| x |(x-a.reduce(:+)/a.length)**2}.reduce(:+)/(a.length-1))**0.5'
R-q-e'sd(扫描(“标准数据”))
给定:
$ myNumbers=$(echo "0.556 1.456 45.111 7.812 5.001" | tr " " "\n")
首先决定你是否需要这些数字的vs
总体标准偏差(Excel中的函数)需要整个数据总体。在Excel中,跳过文本或空格 在
awk
中,可以很容易地滚动计算:
$ echo "$myNumbers" | awk '$1+0==$1 {sum+=$1; sumsq+=$1*$1; cnt++}
END{print sumsq/cnt; print sqrt(sumsq/cnt - (sum/cnt)**2)}'
16.7631
$ echo "$myNumbers" |
awk 'function sdev(array) {
for (i=1; i in array; i++)
sum+=array[i]
cnt=i-1
mean=sum/cnt
for (i=1; i in array; i++)
sqdif+=(array[i]-mean)**2
return (sqdif/(cnt-1))**0.5
}
$1+0==$1 {sum1[++cnt]=$1}
END {print sdev(sum1)}'
18.7417
或者在Ruby中:
$ echo "$myNumbers" | ruby -e 'arr=$<.read.split(/\s/).map { |e| Float(e) rescue nil }.compact
sumsq=arr.inject(0) { |acc, e| acc+=e*e }
p (sumsq/arr.length - (arr.sum/arr.length)**2)**0.5'
16.76307799182477
或者在Ruby中:
$ ruby -lane 'BEGIN{col1=[]}
col1 << Float($F[0]) rescue nil
END {col1.compact
mean=col1.sum / col1.length
p (col1.inject(0){ |acc, e| acc+(e-mean)**2 } /
(col1.length-1))**0.5
}' <(echo "$myNumbers")
18.741690950925424
$ruby-lane'开始{col1=[]}
col1只是为了好玩,8年后,与gnuplot一起:
echo "${myNumbers}" | gnuplot -e 'stats "-" nooutput; print STATS_stddev'
16.7630779918248
作为解释,我让gnuplot对其stdin
上的数据运行stats
函数,抑制正常输出并仅打印标准偏差
相关,但不是答案的一部分。。。您还可以生成许多其他统计数据,如中值、峰度和偏斜、四分位数、最大值和最小值,如下所示:
echo "${myNumbers}" | gnuplot -e 'stats "-"'
样本输出
* FILE:
Records: 5
Out of range: 0
Invalid: 0
Header records: 0
Blank: 0
Data Blocks: 1
* COLUMN:
Mean: 11.9872
Std Dev: 16.7631
Sample StdDev: 18.7417
Skewness: 1.4125
Kurtosis: 3.1303
Avg Dev: 13.2495
Sum: 59.9360
Sum Sq.: 2123.4687
Mean Err.: 7.4967
Std Dev Err.: 5.3010
Skewness Err.: 1.0954
Kurtosis Err.: 2.1909
Minimum: 0.5560 [0]
Maximum: 45.1110 [2]
Quartile: 1.4560
Median: 5.0010
Quartile: 7.8120
这是一个很好的awk循环,当然,这里使用Perl的敏感性是无可争议的。谢谢你的帮助!由于**2
,我得到了'syntax error at or near*',用*(sum/NR)
替换它可以解决这个问题。请注意,这是总体标准偏差与样本标准偏差……至少在我的系统上,octave
命令会短暂启动一个名为octave gui的图形应用程序,除非我添加了--no window system
标志。您可以将std(scanf(“%f”))
替换为std(scanf(“%f”),1)
来计算总体标准偏差,而不是样本标准偏差。@nisetama GUI是GNU Octave 4.0.x以来的默认值,并被更改回Octave 5.0.x
$ ruby -lane 'BEGIN{col1=[]}
col1 << Float($F[0]) rescue nil
END {col1.compact
mean=col1.sum / col1.length
p (col1.inject(0){ |acc, e| acc+(e-mean)**2 } /
(col1.length-1))**0.5
}' <(echo "$myNumbers")
18.741690950925424
echo "${myNumbers}" | gnuplot -e 'stats "-" nooutput; print STATS_stddev'
16.7630779918248
echo "${myNumbers}" | gnuplot -e 'stats "-"'
* FILE:
Records: 5
Out of range: 0
Invalid: 0
Header records: 0
Blank: 0
Data Blocks: 1
* COLUMN:
Mean: 11.9872
Std Dev: 16.7631
Sample StdDev: 18.7417
Skewness: 1.4125
Kurtosis: 3.1303
Avg Dev: 13.2495
Sum: 59.9360
Sum Sq.: 2123.4687
Mean Err.: 7.4967
Std Dev Err.: 5.3010
Skewness Err.: 1.0954
Kurtosis Err.: 2.1909
Minimum: 0.5560 [0]
Maximum: 45.1110 [2]
Quartile: 1.4560
Median: 5.0010
Quartile: 7.8120