2017-05-26 36 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