按照这一理念对numpy ndarray进行漂亮打印的功能,我开发了一个非常原始的原型:
def ndtotext(A, w=None, h=None):
if A.ndim==1:
if w == None :
return str(A)
else:
s ='['+' '*(max(w[-1],len(str(A[0])))-len(str(A[0]))) +str(A[0])
for i,AA in enumerate(A[1:]):
s += ' '*(max(w[i],len(str(AA)))-len(str(AA))+1)+str(AA)
s +='] '
elif A.ndim==2:
w1 = [max([len(str(s)) for s in A[:,i]]) for i in range(A.shape[1])]
w0 = sum(w1)+len(w1)+1
s= u'\u250c'+u'\u2500'*w0+u'\u2510' +'\n'
for AA in A:
s += ' ' + ndtotext(AA, w=w1) +'\n'
s += u'\u2514'+u'\u2500'*w0+u'\u2518'
elif A.ndim==3:
h=A.shape[1]
s1=u'\u250c' +'\n' + (u'\u2502'+'\n')*h + u'\u2514'+'\n'
s2=u'\u2510' +'\n' + (u'\u2502'+'\n')*h + u'\u2518'+'\n'
strings=[ndtotext(a)+'\n' for a in A]
strings.append(s2)
strings.insert(0,s1)
s='\n'.join(''.join(pair) for pair in zip(*map(str.splitlines, strings)))
return s例如:
shape = 4, 5, 3
C=np.random.randint(10000, size=np.prod(shape)).reshape(shape)
print(ndtotext(C))
┌┌────────────────┐┌────────────────┐┌────────────────┐┌────────────────┐┐
│ [9298 4404 1759] [5426 3488 9267] [8884 7721 579] [6872 4226 1858] │
│ [6723 271 8466] [9885 6760 8949] [ 295 7422 5659] [5322 4239 7446] │
│ [7156 6077 9390] [2712 6379 2832] [6956 626 5534] [ 142 4090 6390] │
│ [9377 9033 1953] [8986 3791 4538] [2466 8572 662] [1528 8922 9656] │
│ [1449 7319 3939] [7350 9619 928] [7542 4704 1477] [ 980 6037 869] │
└└────────────────┘└────────────────┘└────────────────┘└────────────────┘┘如果您能够检查这段代码并让我知道如何改进它,我将不胜感激。
我希望看到:
对于那些跟进这个想法的人,我已经把这里的一切都整合到了这个木星笔记本
发布于 2018-11-07 14:55:14
如果A.ndim不在1, 2, 3中,则代码试图返回一个不存在的字符串s。最好明确说明您的代码支持什么是atm:
def ndtotext(A, w=None, h=None):
...
else:
raise NotImplementedError("Currently only 1 - 3 dimensions are supported")
return s当我们即将让您的代码清楚地了解正在发生的事情时,您应该添加一个docstring来解释您的代码所做的事情:
def ndtotext(A, w=None, h=None):
"""Returns a string to pretty print the numpy.ndarray `A`.
Currently supports 1 - 3 dimensions only.
Raises a NotImplementedError if an array with more dimensions is passed.
Describe `w` and `h`.
"""
...接下来,Python有一个正式的风格指南,PEP8,它鼓励程序员遵循。它建议的一件事是在运算符周围加上空格(我在其余代码中修正了这些空间),并将lower_case用于变量和函数(我现在保留了这些空间)。
现在,让我们来看一下您的实际代码:
str(A[0])),将这些值保存到变量中。None进行比较,请使用is (因为它是单例的)。else后的if...return (这是个人风格的问题,我更喜欢没有额外的缩进水平)。str.rjust在字符串前面添加足够的空格。您也可以使用str.format来完成这个任务,但是它看起来不太好。w有一个奇怪的结构,第一列的宽度是最后一个条目,其余的从零开始。str.join。UPPER_LEFT = u'\u250c‘UPPER_RIGHT = u'\u2510’LOWER_LEFT = u'\u2514‘LOWER_RIGHT = u'\u2518’LOWER_RIGHT =u‘\u2518’LOWER_RIGHT= u'\u2500‘垂直= u'\u2502’def upper_line(宽度):返回UPPER_LEFT +水平*宽度+ UPPER_RIGHT def lower_line(宽度):返回LOWER_LEFT +水平*宽度+LOWER_RIGHT def left_line(高度):返回“n”(上部_左边+ 垂向 )*高度+ 较低_左边) def right_line(高度):返回“n”.join(上部_正确的+ 垂向 * height + 较低_正确的)( w=None,h=None):“返回一个字符串以漂亮地打印numpy.ndarray A。目前只支持1-3维。如果传递具有更多维度的数组,则引发NotImplementedError。描述w和h。""“如果A.ndim == 1:如果w是空的:返回str(A) S= ".join(.rjust(宽度)表示值,宽度以zip(A,W)表示))返回'{}'.format(s) elif A.ndim == 2: widths =[max([len(str(A.ndim)) in A*我]) ] for i in range(A.shape1)] =“.join(一个中AA的‘’+ndtotext(中)+‘\n’)w0 =sum(宽度)+len(宽度)-1+2元素与角之间的空格返回upper_line(w0) +‘n’+ lower_line(w0) elif A.ndim == 3: h= A.shape1 strings = 左边_(H)线 strings.extend(ndtotext(a) + '\n‘for a in A) strings.append(right_line(h))返回‘\n’.联接(‘’.联接(对)表示zip中的对(*map(str.splitlines,)引发NotImplementedError(“目前只支持1-3个维度”)这可能会更加紧凑,但我认为这是一个好的开始。
示例用法:
x = np.arange(12)
print(ndtotext(x))
[ 0 1 2 3 4 5 6 7 8 9 10 11]
print(ndtotext(x.reshape(3, 4)))
┌───────────┐
[0 1 2 3]
[4 5 6 7]
[8 9 10 11]
└───────────┘
print(ndtotext(x.reshape(3, 2, 2)))
┌┌─────┐┌─────┐┌───────┐┐
│ [0 1] [4 5] [ 8 9] │
│ [2 3] [6 7] [10 11] │
└└─────┘└─────┘└───────┘┘https://codereview.stackexchange.com/questions/207139
复制相似问题