2014-05-08 39 views
1

構建一個對稱矩陣我有一個文件,該文件,例如,看起來像:在Python從數據文件中

1 1 5.5 
1 2 6.1 
1 3 7.3 
2 2 3.4 
2 3 9.2 
3 3 4.7 

這是一個對稱的3x3矩陣的「半壁江山」。我想在Python中創建完整的對稱矩陣,它看起來像

[[ 5.5 6.1 7.3] 
[ 6.1 3.4 9.2] 
[ 7.3 9.2 4.7]] 

(當然我的實際文件是一個NxN矩陣的一個更大的「半壁江山」,所以我需要比值的一個打字以外的其他解決方案由一)

我已經用盡了所有的資源(書籍和互聯網),我到目前爲止沒有真正接近。任何人都可以幫助我嗎?

謝謝!

+0

你到目前爲止做了什麼?你是否嘗試過實際讀取文件並將其加載到python對象中? – zmo

+0

並查看['numpy'](http://www.numpy.org/) – zmo

+0

您是否事先知道方矩陣的大小? – martineau

回答

0

讀取該文件並加載它作爲一個Python對象,這裏有一個解決方案:

import numpy 

m = numpy.matrix([[0,0,0],[0,0,0],[0,0,0]]) 

with file('matrix.txt', 'r') as f: 
    for l in f: 
     try: 
      i, j, val = line.split(' ') 
      i, j, val = int(i), int(j), float(val) 
      m[i-1,j-1] = val 
     except: 
      print("couldn't load line: {}".format(l)) 

print m 
+0

如果它是對稱的,只有一半是在文件中指定的,您還想添加'm [j,i] = val' – starchild

+0

感謝您的輸入。代碼並沒有真正爲我工作,但經過幾次更正之後,我纔開始工作。我不得不在循環中使用m [i-1,j-1],因爲i和j從1開始並且應該從0開始。另外,我使用了m = numpy.matlib.zeros((N,N)與大NxN矩陣一起工作。再次感謝 – deyan

+0

僅供參考,在Stack Overflow上表達謝意的正確方法是[接受答案](http://meta.stackexchange.com/a/5235)和[up vote it](http:// stackoverflow .com/help/privileges/vote-up),當你有足夠的聲望去做。 ;-) – zmo

0

這裏是完全做到這裏面NumPy的另一種方式。兩個重要的備註:

  • 你可以用np.loadtxt功能直接讀取
  • 您可以在一個行中指定的上半部值正確的索引:N[idxs[:,0] - 1, idxs[:,1] - 1] = vals

下面是代碼:

import numpy as np  
from StringIO import StringIO 

indata = """ 
1 1 5.5 
1 2 6.1 
1 3 7.3 
2 2 3.4 
2 3 9.2 
3 3 4.7 
""" 

infile = StringIO(indata) 

A = np.loadtxt(infile) 

# A is 
# array([[ 1. , 1. , 5.5], 
#  [ 1. , 2. , 6.1], 
#  [ 1. , 3. , 7.3], 
#  [ 2. , 2. , 3.4], 
#  [ 2. , 3. , 9.2], 
#  [ 3. , 3. , 4.7]]) 

idxs = A[:, 0:2].astype(int) 
vals = A[:, 2] 

## To find out the total size of the triangular matrix, note that there 
## are only n * (n + 1)/2 elements that must be specified (the upper 
## half amount for (n^2 - n)/2, and the diagonal adds n to that). 
## Therefore, the length of your data, A.shape[0], must be one solution 
## to the quadratic equation: n^2 + 1 - 2 * A.shape[0] = 0 
possible_sizes = np.roots([1, 1, -2 * A.shape[0]]) 

## Let us take only the positive solution to that equation as size of the 
## result matrix 
size = possible_sizes[possible_sizes > 0] 

N = np.zeros([size] * 2) 

N[idxs[:,0] - 1, idxs[:,1] - 1] = vals 

# N is 
# array([[ 5.5, 6.1, 7.3], 
#  [ 0. , 3.4, 9.2], 
#  [ 0. , 0. , 4.7]]) 

## Here we could do a one-liner like 
# N[idxs[:,1] - 1, idxs[:,0] - 1] = vals 

## But how cool is it to add the transpose and subtract the diagonal? :) 
M = N + np.transpose(N) - np.diag(np.diag(N)) 

# M is 
# array([[ 5.5, 6.1, 7.3], 
#  [ 6.1, 3.4, 9.2], 
#  [ 7.3, 9.2, 4.7]]) 
0

如果您事先知道矩陣的大小(聽起來像是這樣),那麼下面的工作(在Python 2和Python 3中):

N = 3 
symmetric = [[None]*N for _ in range(SIZE)] # pre-allocate output matrix 

with open('matrix_data.txt', 'r') as file: 
    for i, j, val in (line.split() for line in file if line): 
     i, j, val = int(i)-1, int(j)-1, float(val) 
     symmetric[i][j] = val 
     if symmetric[j][i] is None: 
      symmetric[j][i] = val 

print(symmetric) # -> [[5.5, 6.1, 7.3], [6.1, 3.4, 9.2], [7.3, 9.2, 4.7]] 

如果您不知道大小N時間提前,你可以預處理文件,並確定給出的最大指標值。