Shell 矩阵中对角线上的平均值

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.

我有一个矩阵。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.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并愿意接受这样的解决方案?