2017-05-26 40 views
2

我有一个文件格式,如下面的示例所示,显示5个人(包括他们自己)之间的关系。将3列文件转换为矩阵格式

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

如何执行此转换?

+0

在您的真实数据中,键“A”代表“E”代表哪些键?是否需要在输出中按字母顺序排序? –

+0

A到E的实际值是数字(10到13位数字),是的,它需要按数字排序 – roddy

+0

好的,这是有用的信息,所以它应该进入您的问题。可能[编辑]也更新您的示例,因此使用数字而不是字母(它们显然不必包含太多数字!)。 –

回答

2

在这里,我们走了,呆子解决方案:

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 
+0

嗨,谢谢你。它跑了,但我似乎得到了一个不同的订单,你的ID已达到?输入文件按照您的指定分页。 1.0 \t 0.1 \t 0.3 \t 0。2 \t 0.5 0.1 \t 1.0 \t 0.1 \t 0.3 \t 0.3 0.3 \t 0.1 \t 1.0 \t 0.5 \t 0.1 0.2 \t 0.3 \t 0.5 \t 1.0 \t 0.5 0.5 \t 0.3 \t 0.1 \t 0.5 \t 1.0 – roddy

+0

@roddy,我已经使用了你的问题的输入。我正在获得预期的输出(作为您想要的输出)。检查你的文件是否有前导空格/制表符(在第一列之前) – RomanPerekhrest

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 

注意,这个假设的最后一行占有最大的指数。

+0

Thor,上面和下面是相同的,我可以使用任何一种方法。我现在将在一个大文件上测试它们(9,000 x 9,000),并查看哪一个更快。像往常一样感谢所有人的帮助。 – roddy

+0

在我的真实数据集上测试了代码后,它看起来像需要从1向上排列ID的编号。 – roddy

+0

嗨,已经测试了真正的数据集上的代码,它看起来像它需要从1开始向上编号的ID。我的真实ID以8位数字开头,即62243121。 我如何重新编号列1和2从1开始,但确保重新编号列1中的相同ID是否与列2中相同? 再次感谢,Roddy – roddy