我有一个'file.dat',包含24(行)x 16(列)数据。
我已经测试了以下用于计算每列的平均值的awk脚本。
touch aver-std.dat
awk '{ for (i=1; i<=NF; i++) { sum[i]+= $i } }
END { for (i=1; i<=NF; i++ )
{ printf "%f \n", sum[i]/NR} }' file.dat >> aver-std.dat
输出'aver-std.dat'有一列具有这些平均值。
与平均计算类似 我想计算数据文件'file.dat'的每一列的标准偏差,并将其写入输出文件的第二列。 即我想要一个输出文件,其中第一列中的平均值和第二列中的标准差。
我一直在进行不同的测试,比如这个
touch aver-std.dat
awk '{ for (i=1; i<=NF; i++) { sum[i]+= $i }}
END { for (i=1; i<=NF; i++ )
{std[i] += ($i - sum[i])^2 ; printf "%f %f \n", sum[i]/NR, sqrt(std[i]/(NR-1))}}' file.dat >> aver-std.dat
并且它在第二列中写入值,但它们不是标准偏差的正确值。偏差的计算不正确。 我非常感谢任何帮助。 此致
答案 0 :(得分:30)
标准差是
stdev = sqrt((1/N)*(sum of (value - mean)^2))
但是这个公式的另一种形式并不需要你事先知道它的意思。它是:
stdev = sqrt((1/N)*((sum of squares) - (((sum)^2)/N)))
(对于标准差的“平方和”公式的快速网络搜索,如果您感兴趣,将为您提供推导)
要使用此公式,您需要跟踪值的总和和平方和。所以你的awk脚本将改为:
awk '{for(i=1;i<=NF;i++) {sum[i] += $i; sumsq[i] += ($i)^2}}
END {for (i=1;i<=NF;i++) {
printf "%f %f \n", sum[i]/NR, sqrt((sumsq[i]-sum[i]^2/NR)/NR)}
}' file.dat >> aver-std.dat
答案 1 :(得分:13)
要简单地计算数字列表的总体标准差,您可以使用如下命令:
awk '{x+=$0;y+=$0^2}END{print sqrt(y/NR-(x/NR)^2)}'
或者这会计算样本标准差:
awk '{sum+=$0;a[NR]=$0}END{for(i in a)y+=(a[i]-(sum/NR))^2;print sqrt(y/(NR-1))}'
^
在POSIX中。 **
和gawk
支持nawk
,但mawk
不支持def clean(self):
if 'password1' in self.cleaned_data and 'password2' in self.cleaned_data and self.cleaned_data['password1'] != self.cleaned_data['password2']:
raise forms.ValidationError("Passwords do not match")
return cleaned_data
。
答案 2 :(得分:4)
以下是我在研磨机数据输出文件上进行的长时间浸泡测试的计算,该测试必须中断:
标准偏差(有偏见)+平均值
cat <grinder_data_file> | grep -v "1$" | awk -F ', ' '{ sum=sum+$5 ; sumX2+=(($5)^2)} END { printf "Average: %f. Standard Deviation: %f \n", sum/NR, sqrt(sumX2/(NR) - ((sum/NR)^2) )}'
标准差(无偏见)+平均值
cat <grinder_data_file> | grep -v "1$" | awk -F ', ' '{ sum=sum+$5 ; sumX2+=(($5)^2)} END { avg=sum/NR; printf "Average: %f. Standard Deviation: %f \n", avg, sqrt(sumX2/(NR-1) - 2*avg*(sum/(NR-1)) + ((NR*(avg^2))/(NR-1)))}'
答案 3 :(得分:-1)
您的脚本应该以某种方式使用此格式:
awk '{
sum = 0
for (i=1; i<=NF; i++) {
sum += $i
}
avg = sum / NF
avga[NR] = avg
sum = 0
for (i=1; i<=NF; i++) {
sum += ($i - avg) ^ 2
}
stda[NR] = sqrt(sum / NF)
}
END { for (i = 1; i in stda; ++i) { printf "%f %f \n", avga[i], stda[i] } }' file.dat >> aver-std.dat