如何在Python中使用文本标题漂亮地打印NumPy矩阵

4
我有一个关于Python的问题:
如何打印带标题的矩阵,例如这样:
      T  C  G  C  A
  [0 -2 -4 -6 -8 -10]
T [-2  1 -1 -3 -5 -7]
C [-4 -1  2  0 -2 -4]
C [-6 -3  0  1  1 -1]
A [-8 -5 -2 -1  0  2]

我尝试使用numpy.matrix(mat)进行打印,但我得到的结果是:


[[  0  -2  -4  -6  -8 -10]
 [ -2   1  -1  -3  -5  -7]
 [ -4  -1   2   0  -2  -4]
 [ -6  -3   0   1   1  -1]
 [ -8  -5  -2  -1   0   2]]

我也没有成功添加标题。

谢谢!!!

更新

谢谢大家。 我已经成功安装了Pandas,但是我有两个新问题。 以下是我的代码:

import pandas as pd
col1 = [' ', 'T', 'C', 'G', 'C', 'A']
col2 = [' ', 'T', 'C', 'C', 'A']
df = pd.DataFrame(mat,index = col2, columns = col1)
print df

但是我遇到了这个错误:
    df = pd.DataFrame(mat,index = col2, columns = col1)
  File "C:\Python27\lib\site-packages\pandas\core\frame.py", line 163, in __init__
    copy=copy)
  File "C:\Python27\lib\site-packages\pandas\core\frame.py", line 224, in _init_ndarray
    return BlockManager([block], [columns, index])
  File "C:\Python27\lib\site-packages\pandas\core\internals.py", line 237, in __init__
    self._verify_integrity()
  File "C:\Python27\lib\site-packages\pandas\core\internals.py", line 313, in _verify_integrity
    union_items = _union_block_items(self.blocks)
  File "C:\Python27\lib\site-packages\pandas\core\internals.py", line 906, in _union_block_items
    raise Exception('item names overlap')
Exception: item names overlap

当我尝试更改字母时,它可以正常工作:

       T   B   G   C   A  
   0   -2  -4  -6  -8  -10
T  -2  1   -1  -3  -5  -7 
C  -4  -1  2   0   -2  -4 
C  -6  -3  0   1   1   -1 
A  -8  -5  -2  -1  0   2  

但是,正如您所看到的,矩阵的布局并不完全良好。我该如何解决这些问题?


那么,第一行第一列的元素“0”没有标题吗? - Divakar
确实,我可以将它添加为0,但我不愿意这样做。 - Elizabeth
3个回答

4

Numpy并没有提供这样的功能。

(a) pandas

您可以考虑使用pandas。打印pandas.DataFrame通常看起来非常好。

import numpy as np
import pandas as pd
cols = ["T", "C", "S", "W", "Q"]
a = np.random.randint(0,11,size=(5,5))
df = pd.DataFrame(a, columns=cols, index=cols)
print df

将会产生

   T  C   S  W  Q
T  9  5  10  0  0
C  3  8   0  7  2
S  0  2   6  5  8
W  4  4  10  1  5
Q  3  8   7  1  4

(b) 纯 Python

如果您只有纯 Python,您可以使用以下函数。

import numpy as np

def print_array(a, cols, rows):
    if (len(cols) != a.shape[1]) or (len(rows) != a.shape[0]):
        print "Shapes do not match"
        return
    s = a.__repr__()
    s = s.split("array(")[1]
    s = s.replace("      ", "")
    s = s.replace("[[", " [")
    s = s.replace("]])", "]")
    pos = [i for i, ltr in enumerate(s.splitlines()[0]) if ltr == ","]
    pos[-1] = pos[-1]-1
    empty = " " * len(s.splitlines()[0])
    s = s.replace("],", "]")
    s = s.replace(",", "")
    lines = []
    for i, l in enumerate(s.splitlines()):
        lines.append(rows[i] + l)
    s  ="\n".join(lines)
    empty = list(empty)
    for i, p in enumerate(pos):
        empty[p-i] = cols[i]
    s = "".join(empty) + "\n" + s
    print s



c = [" ", "T", "C", "G", "C", "A"]
r = [" ", "T", "C", "C", "A" ]
a = np.random.randint(-4,15,size=(5,6))    
print_array(a, c, r)

给你
       T  C  G  C  A      
  [ 2  5 -3  7  1  9]
T [-3 10  3 -4  8  3]
C [ 6 11 -2  2  5  1]
C [ 4  6 14 11 10  0]
A [11 -4 -3 -4 14 14]

谢谢你的回答,但我该如何下载pandas呢?我已经在网上搜索过了,但是我得到的都是以whl后缀结尾的文件。因此我的电脑无法识别它们。 - Elizabeth

1
考虑一个示例数组 -
In [334]: arr = np.random.randint(0,25,(5,6))

In [335]: arr
Out[335]: 
array([[24,  8,  6, 10,  5, 11],
       [11,  5, 19,  6, 10,  5],
       [ 6,  2,  0, 12,  6, 17],
       [13, 20, 14, 10, 18,  9],
       [ 9,  4,  4, 24, 24,  8]])

我们可以使用Pandas数据框,如下所示 -

import pandas as pd

In [336]: print pd.DataFrame(arr,columns=list(' TCGCA'),index=list(' TCCA'))
        T   C   G   C   A
   24   8   6  10   5  11
T  11   5  19   6  10   5
C   6   2   0  12   6  17
C  13  20  14  10  18   9
A   9   4   4  24  24   8

请注意,pandas数据框期望所有行和列都有标题(列ID)和索引。因此,为了跳过第一行和第一列的标题,我们使用了带有第一个为空的ID:' TCGCA'' TCCA'

谢谢您的回答,但是我已经尝试下载 Pandas,但我得到的都是带有“whl”后缀的文件。我的电脑不知道如何处理它。我该怎么添加 Pandas? - Elizabeth
@Elizabeth 尝试通过pip安装pandas。更多信息请参考- http://askubuntu.com/questions/70883/how-do-i-install-python-pandas - Divakar

0
这是使用纯Python和numpy添加标签的快速版本。
定义一个编写行的函数。这里只是打印出这些行,但可以设置为将其打印到文件中,或者收集所有行并返回它们的列表。
def pp(arr,lbl):
    print('  ','  '.join(lbl))
    for i in range(4):
         print('%s %s'%(lbl[i], arr[i]))

In [65]: arr=np.arange(16).reshape(4,4)

二维数组的默认显示

In [66]: print(arr)
[[ 0  1  2  3]
 [ 4  5  6  7]
 [ 8  9 10 11]
 [12 13 14 15]]

In [67]: lbl=list('ABCD')

In [68]: pp(arr,lbl)
   A  B  C  D
A [0 1 2 3]
B [4 5 6 7]
C [ 8  9 10 11]
D [12 13 14 15]

间距不正确,因为numpy正在单独格式化每一行,并为每一行应用不同的元素宽度。但这是一个开始。

随机样本看起来更好:

In [69]: arr = np.random.randint(0,25,(4,4))
In [70]: arr
Out[70]: 
array([[24, 12, 12,  6],
       [22, 16, 18,  6],
       [21, 16,  0, 23],
       [ 2,  2, 19,  6]])
In [71]: pp(arr,lbl)
   A  B  C  D
A [24 12 12  6]
B [22 16 18  6]
C [21 16  0 23]
D [ 2  2 19  6]

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接