是否有任何优雅的方法可以利用print numpy.array
的正确间距特征来获得具有正确标签的2D数组?例如,给定一个包含4行和5列的数组,如何提供与行和标题列对应的数组和适当大小的列表,以生成一些看起来像这样的输出?
A B C D E
Z [[ 85 86 87 88 89]
Y [ 90 191 192 93 94]
X [ 95 96 97 98 99]
W [100 101 102 103 104]]
如果我天真地尝试:
import numpy
x = numpy.array([[85, 86, 87, 88, 89], \
[90, 191, 192, 93, 94], \
[95, 96, 97, 98, 99], \
[100,101,102,103,104]])
row_labels = ['Z', 'Y', 'X', 'W']
print " A B C D E"
for row, row_index in enumerate(x):
print row_labels[row_index], row
我明白了:
A B C D E
Z [85 86 87 88 89]
Y [90 191 192 93 94]
X [95 96 97 98 99]
W [100 101 102 103 104]
有什么方法可以让事情顺利排队吗?如果有更好的方法来解决我的问题,我绝对愿意使用任何其他库。
答案 0 :(得分:9)
假设所有矩阵编号最多有3位数字,您可以用以下代码替换最后一部分:
print " A B C D E"
for row_label, row in zip(row_labels, x):
print '%s [%s]' % (row_label, ' '.join('%03s' % i for i in row))
哪个输出:
A B C D E
Z [ 85 86 87 88 89]
Y [ 90 191 192 93 94]
X [ 95 96 97 98 99]
W [100 101 102 103 104]
使用'%03s'
格式化会产生长度为3的字符串,并使用左边距(使用空格)。使用'%04s'
作为长度4,依此类推。 Python文档中解释了完整的format string syntax。
答案 1 :(得分:9)
您可以使用IPython notebook + Pandas。在IPython notebook中输入原始示例:
import numpy
x = numpy.array([[85, 86, 87, 88, 89],
[90, 191, 192, 93, 94],
[95, 96, 97, 98, 99],
[100,101,102,103,104]])
row_labels = ['Z', 'Y', 'X', 'W']
column_labels = ['A', 'B', 'C', 'D', 'E']
然后创建一个DataFrame:
import pandas
df = pandas.DataFrame(x, columns=column_labels, index=row_labels)
然后查看它:
答案 2 :(得分:6)
这是一种利用阵列打印功能的方法。我可能不会使用它,但它非常接近满足您的要求!
a = np.random.rand(5,4)
x = np.array('col1 col2 col3 col4'.split())
y = np.array('row1 row2 row3 row4 row5'.split())
b = numpy.zeros((6,5),object)
b[1:,1:]=a
b[0,1:]=x
b[1:,0]=y
b[0,0]=''
printer = np.vectorize(lambda x:'{0:5}'.format(x,))
print printer(b).astype(object)
[[ col1 col2 col3 col4]
[row1 0.95 0.71 0.03 0.56]
[row2 0.56 0.46 0.35 0.90]
[row3 0.24 0.08 0.29 0.40]
[row4 0.90 0.44 0.69 0.48]
[row5 0.27 0.10 0.62 0.04]]
答案 3 :(得分:0)
这段代码本质上是上面scoffey的一个实现,但它没有三个字符限制,而且功能更强大。 这是我的代码:
def format__1(digits,num):
if digits<len(str(num)):
raise Exception("digits<len(str(num))")
return ' '*(digits-len(str(num))) + str(num)
def printmat(arr,row_labels=[], col_labels=[]): #print a 2d numpy array (maybe) or nested list
max_chars = max([len(str(item)) for item in flattenList(arr)+col_labels]) #the maximum number of chars required to display any item in list
if row_labels==[] and col_labels==[]:
for row in arr:
print '[%s]' %(' '.join(format__1(max_chars,i) for i in row))
elif row_labels!=[] and col_labels!=[]:
rw = max([len(str(item)) for item in row_labels]) #max char width of row__labels
print '%s %s' % (' '*(rw+1), ' '.join(format__1(max_chars,i) for i in col_labels))
for row_label, row in zip(row_labels, arr):
print '%s [%s]' % (format__1(rw,row_label), ' '.join(format__1(max_chars,i) for i in row))
else:
raise Exception("This case is not implemented...either both row_labels and col_labels must be given or neither.")
正在运行
import numpy
x = numpy.array([[85, 86, 87, 88, 89],
[90, 191, 192, 93, 94],
[95, 96, 97, 98, 99],
[100,101,102,103,104]])
row_labels = ['Z', 'Y', 'X', 'W']
column_labels = ['A', 'B', 'C', 'D', 'E']
printmat(x,row_labels=row_labels, col_labels=column_labels)
给出
A B C D E
Z [ 85 86 87 88 89]
Y [ 90 191 192 93 94]
X [ 95 96 97 98 99]
W [100 101 102 103 104]
如果'x'只是一个嵌套的python列表而不是numpy数组,那么这也是输出。