我最近注意到Python打印NumPy ndarrays的功能不够一致。例如,它会将水平的1D数组以水平方式打印:
import numpy as np
A1=np.array([1,2,3])
print(A1)
#--> [1 2 3]
但是一个带有冗余括号的1D水平数组:
A2=np.array([[1],[2],[3]])
print(A2)
#--> [[1]
# [2]
# [3]]
将一维垂直数组水平化:
A3=np.array([[1,2,3]])
print(A3)
#--> [[1 2 3]]
还有一个二维数组:
B=np.array([[11,12,13],[21,22,23],[31,32,32]])
print(B)
# --> [[11 12 13]
# [21 22 23]
# [31 32 32]]
第一维现在是垂直的。对于更高的维度来说,情况变得更糟,因为它们全部都是垂直打印的:
C=np.array([[[111,112],[121,122]],[[211,212],[221,222]]])
print(C)
#--> [[[111 112]
# [121 122]]
#
# [[211 212]
# [221 222]]]
在我看来,一致的行为应该是水平打印偶数维度和垂直打印奇数维度。使用Unicode字符可以将其格式化得很好。我想知道是否有可能创建一个函数来打印上述数组:
A1 --> [1 2 3]
A2 --> ┌┌─┐┌─┐┌─┐┐
│ 1 2 3 │
└└─┘└─┘└─┘┘
A3 --> ┌┌─┐┐ # \u250c\u2500\u2510
│ 1 │ # \u2502
│ 2 │
│ 3 │
└└─┘┘ # \u2514\u2500\u2518
B --> ┌┌──┐┌──┐┌──┐┐
│ 11 21 31 │
│ 12 22 32 │
│ 13 23 33 │
└└──┘└──┘└──┘┘
C --> ┌┌─────────┐┌─────────┐┐
│ [111 112] [211 212] │
│ [121 122] [221 222] │
└└─────────┘└─────────┘┘
我发现这个代码片段可以处理不同位数的数字。我尝试原型化了一个递归函数来实现上述概念:
def npprint(A):
assert isinstance(A, np.ndarray), "input of npprint must be array like"
if A.ndim==1 :
print(A)
else:
for i in range(A.shape[1]):
npprint(A[:,i])
它对于
A1
、A2
、A3
和B
有点用,但对于C
不起作用。我希望你能帮我知道如何使用npprint
来实现任意维度的numpy ndarrays的上述输出。请注意:在Jupyter环境中,可以在Markdown中使用LaTeX \mathtools
, \underbracket
和\overbracket
。Sympy的漂亮打印功能也是一个很好的起点,它可以使用ASCII、Unicode、LaTeX等格式。有人告诉我ndarrays的打印方式确实是一致的,但在我看来它有点奇怪和不直观。有一个灵活的漂亮打印函数可以帮助我们以不同的形式显示ndarrays。Sympy的开发者已经考虑到了我在这里提到的两个问题。他们的矩阵模块非常一致(A1
和A2
是相同的),他们还有一个pprint
函数,它做了类似的事情,我期望npprint也能实现这样的效果。如果您有兴趣,请查看此Jupyter Notebook。
A2
的形状为 (3,1)。第一维垂直打印,第二维按列打印。C
是 (2,2,2),第一维以空格分隔块显示,其余维度与 2DB
相同,按行/列显示。请注意方括号的使用,它们与等价列表的嵌套匹配。 - hpauljA2
没有多余的括号。A3
也是如此。形状与A1
不同。括号很重要。 - hpauljnumpy
的显示是一致的。最后一个维度(最内层)总是列。倒数第二个是行。然后用空格、括号和缩进分隔块。然后是更高级别的分隔。在 2D 屏幕上显示 3D 及以上的数组总会有问题(这也适用于编写 CSV 文件)。但是,实际工作中的数组通常太大而无法完整显示,无论布局如何。 - hpauljndarray
的数据存储方式与list
完全不同。0维数组与数组标量并不完全相同,而它们也与Python标量不完全相同。参考链接:https://docs.scipy.org/doc/numpy-1.15.0/reference/arrays.html。 - hpaulj