2013-03-15 198 views
1

我被卡住了(並且在一段時間緊縮)並希望得到一些幫助。這可能是一個簡單的任務,但我似乎無法解決它..重新排列具有命名的列/行的矩陣python

我有一個矩陣,比如說5乘5,一個額外的起始列的名稱行和相同名稱的列在一個文本文件是這樣的:

b e a d c 
b 0.0 0.1 0.3 0.2 0.5 
e 0.1 0.0 0.4 0.9 0.3 
a 0.3 0.4 0.0 0.7 0.6 
d 0.2 0.9 0.7 0.0 0.1 
c 0.5 0.3 0.6 0.1 0.0 

我有兩個具有相同的格式和矩陣的大小,但名稱的順序是不同的多個文件。我需要一種方法來改變這些,所以它們都是一樣的,並保持0.0對角線。因此,我必須對列進行交換,我必須對行進行交換。

我一直在尋找一點,似乎NumPy可能會做我想做的事情,但我從來沒有使用它或數組。任何幫助是極大的讚賞!

簡而言之:如何將文本文件導入到一個數組中,然後我可以將行和列交換爲所需的順序?

回答

4

我建議你用熊貓:

from StringIO import StringIO 
import pandas as pd 
data = StringIO("""b e a d c 
b 0.0 0.1 0.3 0.2 0.5 
e 0.1 0.0 0.4 0.9 0.3 
a 0.3 0.4 0.0 0.7 0.6 
d 0.2 0.9 0.7 0.0 0.1 
c 0.5 0.3 0.6 0.1 0.0 
""") 
df = pd.read_csv(data, sep=" ") 
print df.sort_index().sort_index(axis=1) 

輸出:

 a b c d e 
a 0.0 0.3 0.6 0.7 0.4 
b 0.3 0.0 0.5 0.2 0.1 
c 0.6 0.5 0.0 0.1 0.3 
d 0.7 0.2 0.1 0.0 0.9 
e 0.4 0.1 0.3 0.9 0.0 
+0

完美。謝謝。 – Binnie 2013-03-18 16:24:36

+0

有沒有方法可以打印沒有列/行名稱的矩陣? – Binnie 2013-03-19 19:51:52

+0

是的,'print df.to_string(header = False,index = False)' – HYRY 2013-03-19 21:26:08

0

下面是一個可怕的numpy的版本開始(使用HYRY的答案...)

import numpy as np 

with open("myfile", "r") as myfile: 
    lines = myfile.read().split("\n") 
    floats = [[float(item) for item in line.split()[1:]] for line in lines[1:]] 
    floats_transposed = np.array(floats).transpose().tolist() 
0
from copy import copy 

f = open('input', 'r') 
data = [] 
for line in f: 
    row = line.rstrip().split(' ') 
    data.append(row) 

#collect labels, strip empty spaces 
r = data.pop(0) 
c = [row.pop(0) for row in data] 
r.pop(0) 

origrow, origcol = copy(r), copy(c) 

r.sort() 
c.sort() 

newgrid = [] 
for row, rowtitle in enumerate(r): 
    fromrow = origrow.index(rowtitle) 
    newgrid.append(range(len(c))) 
    for col, coltitle in enumerate(c): 
     #We ask this len(row) times, so memoization 
     #might matter on a large matrix 
     fromcol = origcol.index(coltitle) 
     newgrid[row][col] = data[fromrow][fromcol] 

print "\t".join([''] + r) 
clabel = c.__iter__() 
for line in newgrid: 
    print "\t".join([clabel.next()] + line)