Shell 矩阵中对角线上的平均值
我有一个矩阵。e、 g.5 x 5矩阵Shell 矩阵中对角线上的平均值,shell,matrix,awk,diagonal,canonicalization,Shell,Matrix,Awk,Diagonal,Canonicalization,我有一个矩阵。e、 g.5 x 5矩阵 $ cat input.txt 1 5.6 3.4 2.2 -9.99E+10 2 3 2 2 -9.99E+10 2.3 3 7 4.4 5.1 4 5 6 7 8 5 -9.99E+10 9 11 13 这里我想忽略-9.
$ cat input.txt
1 5.6 3.4 2.2 -9.99E+10
2 3 2 2 -9.99E+10
2.3 3 7 4.4 5.1
4 5 6 7 8
5 -9.99E+10 9 11 13
这里我想忽略-9.99E+10值
我正在寻找对角线分割后所有条目的平均值。以下是四种可能性(使用999
代替-9.99E+10
以节省图形空间):
我想平均不同阴影三角形下的所有值。
所以欲望输出是:
$cat outfile.txt
P1U 3.39 (Average of all values of Lower side of Possible 1 without considering -9.99E+10)
P1L 6.88 (Average of all values of Upper side of Possible 1 without considering -9.99E+10)
P2U 4.90
P2L 5.59
P3U 3.31
P3L 6.41
P4U 6.16
P4L 4.16
很难开发一个合适的算法来用fortran或shell脚本编写它。
我正在考虑下面的算法,但无法思考下一步是什么
step 1: #Assign -9.99E+10 to the Lower diagonal values of a[ij]
for i in {1..5};do
for j in {1..5};do
a[i,j+1]=-9.99E+10
done
done
step 2: #take the average
sum=0
for i in {1..5};do
for j in {1..5};do
sum=sum+a[i,j]
done
done
printf "%s %5.2f",P1U, sum
step 3: #Assign -9.99E+10 to the upper diagonal values of a[ij]
for i in {1..5};do
for j in {1..5};do
a[i-1,j]=-9.99E+10
done
done
step 4: #take the average
sum=0
for i in {1..5};do
for j in {1..5};do
sum=sum+a[i,j]
done
done
printf "%s %5.2f",P1L,sum
只需将所有值保存在按行和列编号索引的aray中,然后在结束部分中,在定义每个部分的循环时,根据需要重复设置开始和结束行和列循环分隔符的过程:
$ cat tst.awk
{
for (colNr=1; colNr<=NF; colNr++) {
vals[colNr,NR] = $colNr
}
}
END {
sect = "P1U"
begColNr = 1; endColNr = NF; begRowNr = 1; endRowNr = NR
sum = cnt = 0
for (rowNr=begRowNr; rowNr<=endRowNr; rowNr++) {
for (colNr=begRowNr; colNr<=endColNr-rowNr+1; colNr++) {
val = vals[colNr,rowNr]
if ( val != "-9.99E+10" ) {
sum += val
cnt++
}
}
}
printf "%s %.2f\n", sect, (cnt ? sum/cnt : 0)
sect = "P1L"
begColNr = 1; endColNr = NF; begRowNr = 1; endRowNr = NR
sum = cnt = 0
for (rowNr=begRowNr; rowNr<=endRowNr; rowNr++) {
for (colNr=endColNr-rowNr+1; colNr<=endColNr; colNr++) {
val = vals[colNr,rowNr]
if ( val != "-9.99E+10" ) {
sum += val
cnt++
}
}
}
printf "%s %.2f\n", sect, (cnt ? sum/cnt : 0)
}
我假设在处理第一象限对角对半部分时,您可以计算出其他象限对角对半部分,水平/垂直象限对半部分很简单(只需将begRowNr设置为int(NR/2)+1或endRowNr设置为int(NR/2)或begColNr设置为int(NF/2)+1或endColNr设置为int(NF/2)然后循环每个循环的结果值的完整范围。只需将所有值保存在一个由行和列编号索引的数组中,然后在结束部分重复此过程,在为每个部分定义循环时,根据需要设置开始和结束行和列循环分隔符:
$ cat tst.awk
{
for (colNr=1; colNr<=NF; colNr++) {
vals[colNr,NR] = $colNr
}
}
END {
sect = "P1U"
begColNr = 1; endColNr = NF; begRowNr = 1; endRowNr = NR
sum = cnt = 0
for (rowNr=begRowNr; rowNr<=endRowNr; rowNr++) {
for (colNr=begRowNr; colNr<=endColNr-rowNr+1; colNr++) {
val = vals[colNr,rowNr]
if ( val != "-9.99E+10" ) {
sum += val
cnt++
}
}
}
printf "%s %.2f\n", sect, (cnt ? sum/cnt : 0)
sect = "P1L"
begColNr = 1; endColNr = NF; begRowNr = 1; endRowNr = NR
sum = cnt = 0
for (rowNr=begRowNr; rowNr<=endRowNr; rowNr++) {
for (colNr=endColNr-rowNr+1; colNr<=endColNr; colNr++) {
val = vals[colNr,rowNr]
if ( val != "-9.99E+10" ) {
sum += val
cnt++
}
}
}
printf "%s %.2f\n", sect, (cnt ? sum/cnt : 0)
}
我假设在处理第一象限对角对半部分时,您可以计算出其他象限对角对半部分,水平/垂直象限对半部分很简单(只需将begRowNr设置为int(NR/2)+1或endRowNr设置为int(NR/2)或begColNr设置为int(NF/2)+1或endColNr设置为int(NF/2)然后循环遍历每个值的结果完整范围。您可以在一次迭代中计算所有值
$ awk -v NA='-9.99E+10' '{for(i=1;i<=NF;i++) a[NR,i]=$i}
END {for(i=1;i<=NR;i++)
for(j=1;j<=NF;j++)
{v=a[i,j];
if(v!=NA)
{if(i+j<=6) {p["1U"]+=v; c["1U"]++}
if(i+j>=6) {p["1L"]+=v; c["1L"]++}
if(j>=i) {p["2U"]+=v; c["2U"]++}
if(i<=3) {p["3U"]+=v; c["3U"]++}
if(i>=3) {p["3D"]+=v; c["3D"]++}
if(j<=3) {p["4U"]+=v; c["4U"]++}
if(j>=3) {p["4D"]+=v; c["4D"]++}}}
for(k in p) printf "P%s %.2f\n", k,p[k]/c[k]}' file | sort
P1L 6.88
P1U 3.39
P2U 4.90
P3D 6.41
P3U 3.31
P4D 6.16
P4U 4.16
$awk-vna='-9.99E+10'{for(i=1;i您可以在一次迭代中计算所有
$ awk -v NA='-9.99E+10' '{for(i=1;i<=NF;i++) a[NR,i]=$i}
END {for(i=1;i<=NR;i++)
for(j=1;j<=NF;j++)
{v=a[i,j];
if(v!=NA)
{if(i+j<=6) {p["1U"]+=v; c["1U"]++}
if(i+j>=6) {p["1L"]+=v; c["1L"]++}
if(j>=i) {p["2U"]+=v; c["2U"]++}
if(i<=3) {p["3U"]+=v; c["3U"]++}
if(i>=3) {p["3D"]+=v; c["3D"]++}
if(j<=3) {p["4U"]+=v; c["4U"]++}
if(j>=3) {p["4D"]+=v; c["4D"]++}}}
for(k in p) printf "P%s %.2f\n", k,p[k]/c[k]}' file | sort
P1L 6.88
P1U 3.39
P2U 4.90
P3D 6.41
P3U 3.31
P4D 6.16
P4U 4.16
$awk-vna='-9.99E+10'{for(i=1;我将介绍Stack Overflow。这是一个面向专业和热心程序员的问答网站。目标是您在问题中添加一些自己的代码,以至少显示您自己为解决此问题所做的研究工作。我做了很多研究,但无法做到。我已更新了代码。谢谢。您熟悉wi吗th python/numpy,是否有机会接受这样的解决方案?欢迎使用Stack Overflow。这也是一个面向专业和热心程序员的问答网站。目标是您在问题中添加一些自己的代码,以显示您自己为解决此问题所做的研究工作。我做了很多研究,但无法做到。我已经更新了我的代码。谢谢。您是否熟悉python/numpy并愿意接受这样的解决方案?