将3列文件转换为矩阵格式

时间:2017-05-26 09:13:17

标签: awk

我有一个类似下面示例的文件格式,显示包括他们自己在内的5个人之间的关系。

1   1   1.0
2   1   0.5
3   1   0.1
4   1   0.3
5   1   0.1
2   2   1.0
3   2   0.5
4   2   0.2
5   2   0.3
3   3   1.0
4   3   0.5
5   3   0.3
4   4   1.0
5   4   0.1
5   5   1.0

我想使用AWK将其转换为完整的矩阵格式。我需要按照示例的方式对行和列进行数字排序。

    1   2   3   4   5
1   1.0 0.5 0.1 0.3 0.1
2   0.5 1.0 0.5 0.2 0.3
3   0.1 0.5 1.0 0.5 0.3
4   0.3 0.2 0.5 1.0 0.1
5   0.1 0.3 0.3 0.1 1.0

我遇到了一个上一个帖子(下面),但输入文件的格式略有不同,我正在努力调整它。 http://www.unix.com/shell-programming-and-scripting/203483-how-rearrange-matrix-awk.html

如何执行此转换?

2 个答案:

答案 0 :(得分:2)

我们走了, gawk 解决方案:

matrixize.awk 脚本:

#!/bin/awk -f
BEGIN { OFS="\t" }     # output field separator
{
    b[$1];             # accumulating unique indices
    if ($1 != $2) {   
        a[$2][$1] = $3 # set `diagonal` relation between different indices 
    } 
    a[$1][$2] = $3     # multidimensional array (reflects relation `one-to-many`)
}
END {
    asorti(b); h = "";  # sort unique indices
    for (i in b) {
        h = h OFS i     # form header columns
    } 
    print h;            # print header column values
    for (i in b) { 
        row = i;        # index column
        # iterating through the row values (for each intersection point)
        for (j in a[i]) {
            row = row OFS a[i][j]
        } 
        print row  
    }
}

<强> 用法

awk -f matrixize.awk yourfile

输出:

    1   2   3   4   5
1   1.0 0.5 0.1 0.3 0.1
2   0.5 1.0 0.5 0.2 0.3
3   0.1 0.5 1.0 0.5 0.3
4   0.3 0.2 0.5 1.0 0.1
5   0.1 0.3 0.3 0.1 1.0

答案 1 :(得分:1)

由于上三角和下三角相同,将每个元素对复制到多维数组中的两个索引是不够的,例如:

parse.awk

{ h[$1,$2] = h[$2,$1] = $3 }

END {
  for(i=1; i<=$1; i++) {
    for(j=1; j<=$2; j++)
      printf h[i,j] OFS
    printf "\n"
  }
}

执行命令

awk -f parse infile

输出:

1.0 0.5 0.1 0.3 0.1 
0.5 1.0 0.5 0.2 0.3 
0.1 0.5 1.0 0.5 0.3 
0.3 0.2 0.5 1.0 0.1 
0.1 0.3 0.3 0.1 1.0

请注意,这假设最后一行包含最大的索引。