Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

computing element-wise averages from matrices

Tags:

bash

sed

awk

I've a set of matrices stored in text files. I would like to compute an output matrix resulting of the element-wise averages of the input matrices. An illustration is given below:

cat file1.txt
Item0 Item1
Item0 1.01456e+06 5
Item1 2 12.2


cat file2.txt
Item0 Item1
Item0 1.0274e+06 6
Item1 0 14.5


cat output.txt
Item0 Item1
Item0 1020980 5.5
Item1 1 13.35

Note that some of the values in the input matrices are in engineering notation. All suggestions are welcomed!

like image 717
Tin Avatar asked Sep 12 '26 21:09

Tin


2 Answers

awk -v row=2:3 -v col=2:3 -v num=2 '

BEGIN {
    split(row, r, ":")
    split(col, c, ":")
    n = num
}

r[1]<=FNR && FNR<=r[2] {
    for(i=c[1];i<=c[2];i++)
    {
        m[FNR,i]+=$i
    }
}

END {
    for(i=r[1];i<=r[2];i++)
    {
        for(j=c[1];j<=c[2];j++)
        {
            printf("%f\t", m[i,j]/n)
        }
        print ""
    }
}' file{1,2}.txt

1020980.000000  5.500000
1.000000        13.350000
like image 177
kev Avatar answered Sep 14 '26 15:09

kev


I'd suggest doing this in two stages. First, convert the matrices to lines of (row number, column number, value) triples. I'll assume matrices without the row and column labels, for simplicity.

for f in file*.txt
do
  awk '{ for (n=1; n<=NF; n++) { print NR, n, $n } }' $f
done

This first step throws all the matrices together in a way that is more easily handled.

Next, calculate the averages by piping the triples into awk:

awk -v Rows=2 -v Cols=2 Mats=2 '
{
  sum[$1, $2] += $3
}

END {
  for (m=1; m<=Rows; m++) {
    for (n=1; n<=Cols; n++) {
      printf("%s ", sum[m, n])
    }
    printf("\n")
  }
}'

For simplicity, I've just passed in the numbers of rows, columns, and matrices as awk variables. You could instead determine those from the triples.

like image 38
Michael J. Barber Avatar answered Sep 14 '26 15:09

Michael J. Barber



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!