2013-03-15 167 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)