我有很多( nTotal )个文件,每个文件都有一列长度 L 的浮点数,我想在所有这些文件的第i_行添加条目在末尾。计算其平均值和标准差。 我先读了每个文件。然后我尝试将此数组添加到一个数组,这给我一个语法错误:(standard_in)2:语法错误。我希望 suma [i] 包含现在所有文件的第i_行的所有条目的总和。然后我找到平均值 修改我按照建议更改了for循环。
for (( n= 1 ; n < $nTotal; n++ ))
do
IFS=$'\n'
arr1=($(./a.out filename | sed 's/:.*//'))
for (( i= 1 ; i < $L; i++ ))
do
sum[i]=`echo "${sum[i]} - ${arr1[i]}" | bc`
done
done
for (( i= 1 ; i < $L; i++ ))
do
ya=$(echo -1*${sum[i]} | bc)
aveSum=$(echo $ya/$nTotal | bc -l)
done
编辑: ./a.out生成一列浮点数的文件。
为了找到标准偏差,我再次读取数据文件并将它们存储在数组中(我确信这不是最聪明的方法,但我想不出别的什么。 )。我也找不到标准偏差:
for (( i= 1 ; i < $L; i++ ))
do
ya=$(echo -1*${sum[i]} | bc)
ta=$(echo $ya/$nTotal | bc -l)
tempval=`echo "${arr1[i]} - $ta * ${arr1[i]} - $ta" | bc`
val[i]=`echo "${val[i]} - $tempval" | bc`
done
这里我的 val [i] 元素为零,我无法弄清楚是什么问题。如果你可以指导我解决这个问题,我将非常感激。
答案 0 :(得分:1)
对于这个问题,Bash可能不是最简单的,特别是因为它没有实现非整数运算。我用awk:
awk '{ n[FNR]++;
delta = $1 - mean[FNR];
mean[FNR] += delta / n[FNR];
m2[FNR] += delta * ($1 - mean[FNR]);
}
END {for (i=1; i in n; ++i)
print mean[i], sqrt(m2[i]/(n[i]-1));
}' file1 file2 ...
数学直接取自众所周知的"online" mean and variance algorithms。该程序假定所有文件都有L
行,但如果少数或多或少,则只会忽略丢失的数据;你可能想做一个更好的有效性测试。在特定情况下,只有一个文件有太多行,标准偏差计算将陷入零除;在一次阅读中,这并不重要,因为已经打印了正确的数据,但您也可能想要解决这个问题。
该程序使用了几个awk特性:首先,数组被自动(并且懒惰地)初始化为0(如果用作数字);第二,FNR
是当前文件中的行号。 (NR
是输入中的行号,但在这种情况下FNR
更有用。)