2012-06-19 162 views
14

我有一個多維矩陣(使用numpy),我想添加行/列標題。數據實際上是7x12x12,但我可以這樣表示:將行/列標題添加到Numpy矩陣

A=[[[0, 1, 2, 3, 4, 5], 
     [1, 0, 3, 4, 5, 6], 
     [2, 3, 0, 5, 6, 7], 
     [3, 4, 5, 0, 7, 8], 
     [4, 5, 6, 7, 0, 9], 
     [5, 6, 7, 8, 9, 0]] 


    [[0, 1, 2, 3, 4, 5], 
     [1, 0, 3, 4, 5, 6], 
     [2, 3, 0, 5, 6, 7], 
     [3, 4, 5, 0, 7, 8], 
     [4, 5, 6, 7, 0, 9], 
     [5, 6, 7, 8, 9, 0]]] 

其中A是我的2x6x6矩陣。

在任何情況下, 如何插入穿過第一行和第一列標題,讓每一個矩陣如下所示:

 A, a, b, c, d, e, f 
     a, 0, 1, 2, 3, 4, 5, 
     b, 1, 0, 3, 4, 5, 6, 
     c, 2, 3, 0, 5, 6, 7, 
     d, 3, 4, 5, 0, 7, 8, 
     e, 4, 5, 6, 7, 0, 9, 
     f, 5, 6, 7, 8, 9, 0 
在我的CSV輸出文件

現在我已經做了矩陣7x13x13,並插入數據,使我有一個行和列的0,但我更喜歡字符串。我想我可以只寫一個Excel宏來替換字符串中的零...問題是numpy不能將字符串轉換爲浮點數,如果我嘗試重新分配那些0作爲我想要的字符串。

+0

林不熟悉numpy的,但是這將是很直如果他們只是列表,則轉發。該訂單的解決方案是否可以接受?你可以將numpy矩陣轉換爲列表嗎? –

+0

numpy矩陣的工作方式,他們可以作爲列表的列表,所以你可以迭代他們就好了。 – JAB

回答

9

numpy將處理n維數組的罰款,但可能的設施限於2維數組。甚至不知道你希望輸出文件的外觀。

許多希望命名列的人忽略了numpy的recarray()功能。好東西知道,但只有「命名」一維。

對於兩個維度,Pandas是非常酷的。

In [275]: DataFrame.from_items([('A', [1, 2, 3]), ('B', [4, 5, 6])], 
    .....:      orient='index', columns=['one', 'two', 'three']) 
Out[275]: 
    one two three 
A 1 2  3 
B 4 5  6 

如果輸出是你正試圖在這裏解決的唯一問題,我可能只是手工編碼魔法的幾行堅持,因爲它會比安裝其他包一個功能較少的分量。

+0

熊貓正是我一直在尋找的東西。 – emmagras

1

我不知道任何方法來添加標題到矩陣(即使我會覺得它有用)。我會做的是創建一個小類,爲我打印對象,並重載__str__函數。

事情是這樣的:

class myMat: 
    def __init__(self, mat, name): 
     self.mat = mat 
     self.name = name 
     self.head = ['a','b','c','d','e','f'] 
     self.sep = ',' 

    def __str__(self): 
     s = "%s%s"%(self.name,self.sep) 
     for x in self.head: 
      s += "%s%s"%(x,self.sep) 
     s = s[:-len(self.sep)] + '\n' 

     for i in range(len(self.mat)): 
      row = self.mat[i] 
      s += "%s%s"%(self.head[i],self.sep) 
      for x in row: 
       s += "%s%s"%(str(x),self.sep) 
      s += '\n' 
     s = s[:-len(self.sep)-len('\n')] 

     return s 

然後你可以只輕鬆地用頭打印出來,使用下面的代碼:

print myMat(A,'A') 
print myMat(B,'B') 
+0

這看起來很有希望。在試圖提煉我的問題時,我把事情混淆了,因爲大矩陣實際上並不是由標記爲較小的矩陣組成的。我試圖分割它並實施您的建議,但它不起作用。對於初學者,我有一個「列表索引超出範圍」在這條線s + =「%s%s」%(self.head [i],self.sep) 如果您的建議改變只有矩陣,而不是處理矩陣的彙編矩陣? – emmagras

+0

我猜你會得到一個索引超出範圍的錯誤,由於矩陣的大小不同。此時此代碼僅適用於6x6矩陣(即len(['a','b','c','d','e','f'])))。只需將定義self.head的行改爲矩陣大小(例如,如果矩陣是3x3,則該行應該看起來像self.head = ['a','b','c'])。希望這可以幫助! –

3

想想這樣做的伎倆一般

輸入

mats = array([[[0, 1, 2, 3, 4, 5], 
    [1, 0, 3, 4, 5, 6], 
    [2, 3, 0, 5, 6, 7], 
    [3, 4, 5, 0, 7, 8], 
    [4, 5, 6, 7, 0, 9], 
    [5, 6, 7, 8, 9, 0]], 

    [[0, 1, 2, 3, 4, 5], 
    [1, 0, 3, 4, 5, 6], 
    [2, 3, 0, 5, 6, 7], 
    [3, 4, 5, 0, 7, 8], 
    [4, 5, 6, 7, 0, 9], 
    [5, 6, 7, 8, 9, 0]]]) 

代碼

# Recursively makes pyramiding column and row headers 
def make_head(n): 
    pre = '' 
    if n/26: 
     pre = make_head(n/26-1) 

    alph = "abcdefghijklmnopqrstuvwxyz" 
    pre+= alph[n%26] 
    return pre 

# Generator object to create header items for n-rows or n-cols 
def gen_header(nitems): 
    n = -1 
    while n<nitems: 
     n+=1 
     yield make_head(n) 

# Convert numpy to list 
lmats = mats.tolist() 

# Loop through each "matrix" 
for mat in lmats: 
    # Pre store number of columns as we modify it before working rows 
    ncols = len(mat[0]) 

    # add header value to front of each row from generator object 
    for row,hd in zip(mat,gen_header(len(mat))): 
     row.insert(0,hd) 

    # Create a "header" line for all the columns 
    col_hd = [hd for hd in gen_header(ncols-1)] 
    col_hd.insert(0,"A") 

    # Insert header line into lead row of matrix 
    mat.insert(0,col_hd) 

# Convert back to numpy 
mats = numpy.array(lmats) 

輸出(存儲在墊子值):

array([[['A', 'a', 'b', 'c', 'd', 'e', 'f'], 
     ['a', '0', '1', '2', '3', '4', '5'], 
     ['b', '1', '0', '3', '4', '5', '6'], 
     ['c', '2', '3', '0', '5', '6', '7'], 
     ['d', '3', '4', '5', '0', '7', '8'], 
     ['e', '4', '5', '6', '7', '0', '9'], 
     ['f', '5', '6', '7', '8', '9', '0']], 

     [['A', 'a', 'b', 'c', 'd', 'e', 'f'], 
     ['a', '0', '1', '2', '3', '4', '5'], 
     ['b', '1', '0', '3', '4', '5', '6'], 
     ['c', '2', '3', '0', '5', '6', '7'], 
     ['d', '3', '4', '5', '0', '7', '8'], 
     ['e', '4', '5', '6', '7', '0', '9'], 
     ['f', '5', '6', '7', '8', '9', '0']]], 
     dtype='|S4') 
+0

我收到一個錯誤''numpy.ndarray'對象沒有屬性'insert'' 任何解決方法建議? – emmagras

+0

解決方法包括。我將numpy墊子轉換成列表進行操作並轉換回來。 Numpy插入例程非常愚蠢,或者我看不出它們是如何有用的 –

+0

謝謝。我終於明白了這一點。 – emmagras

1

不能確定,但​​可以考慮在看看Pandas

21

隨着pandas.DataFrame.to_csv你可以寫列和索引文件:

import numpy as np 
import pandas as pd 

A = np.random.randint(0, 10, size=36).reshape(6, 6) 
names = [_ for _ in 'abcdef'] 
df = pd.DataFrame(A, index=names, columns=names) 
df.to_csv('df.csv', index=True, header=True, sep=' ') 

會給你以下df.csv文件:

a b c d e f 
a 1 5 5 0 4 4 
b 2 7 5 4 0 9 
c 6 5 6 9 7 0 
d 4 3 7 9 9 3 
e 8 1 5 1 9 0 
f 2 8 0 0 5 1  
+1

這是特別有用的,因爲它包含導入命令和關於如何寫入文件的信息。真棒。 – emmagras

+0

謝謝。如果你說我的答案很棒,那就考慮放棄它;-) – bmu