第一个答案
如果我正确理解了您的问题(还有 4 个其他答案说我没有),您的问题不是如何 flatten() 或 reshape(-1) 一个数组,而是如何确保即使在重塑之后,它仍然显示每个元素 4 个线。
我不认为你可以,严格来说。数组只是一堆元素。它们不包含有关我们希望如何查看它们的指示。那是打印问题,您应该在打印时解决。您可以在 [here][1] 看到想要这样做的人......从在 2D 中重塑数组开始。
话虽如此,在不创建自己的打印功能的情况下,您可以使用np.set_printoptions 控制 numpy 显示数组的方式。
尽管如此,它还是很棘手,因为这个函数只允许您指定每行打印多少个字符,而不是元素。所以你需要知道每个元素需要多少个字符来强制换行。
在您的示例中:
np.set_printoptions(formatter={"all":lambda x:"{:>6}".format(x)}, linewidth=7+(6+2)*4)
格式化程序确保每个数字使用 6 个字符。
线宽,考虑到 "array([" 部分,以及结束 "])" (9 chars) 加上每个元素之间的 2 ", ",知道我们想要 4 个元素,必须是 9+6×4+2× 3:“array([...])” 9 个字符,每 4 个数字 6×4,每 3 个“,” 分隔符 2×3。或 7+(6+2)×4。
您只能将其用于一次打印
with np.printoptions(formatter={"all":lambda x:"{:>6}".format(x)}, linewidth=7+(6+2)*4):
print(s.reshape(-1))
一段时间后编辑:子类
我想到的另一种方法是将ndarray 子类化,使其行为符合您的要求
import numpy as np
class MyArr(np.ndarray):
# To create a new array, with args ls: number of element to print per line, and arr, normal array to take data from
def __new__(cls, ls, arr):
n=np.ndarray.__new__(MyArr, (len(arr,)))
n.ls=ls
n[:]=arr[:]
return n
def __init__(self, *args):
pass
# So that this .ls is viral: when ever the array is created from an operation from an array that has this .ls, the .ls is copyied in the new array
def __array_finalize__(self, obj):
if not hasattr(self, 'ls') and type(obj)==MyArr and hasattr(obj, 'ls'):
self.ls=obj.ls
# Function to print an array with .ls elements per line
def __repr__(self):
# For other than 1D array, just use standard representation
if len(self.shape)!=1:
return super().__repr__()
mxsize=max(len(str(s)) for s in self)
s='['
for i in range(len(self)):
if i%self.ls==0 and i>0:
s+='
'
s+=f'{{:{mxsize}}}'.format(self[i])
if i+1<len(self): s+=', '
s+=']'
return s
现在你可以使用这个MyArr 来构建你自己的一维数组
MyArr(4, range(12))
节目
[ 0.0, 1.0, 2.0, 3.0,
4.0, 5.0, 6.0, 7.0,
8.0, 9.0, 10.0, 11.0]
您可以在任何一维 ndarray 合法的地方使用它。大多数时候,.ls 属性会随之而来(我说“大部分时间”,因为我不能保证某些函数不会构建新的 ndarray,并用来自这个的数据填充它们)
a=MyArr(4, range(12))
a*2
#[ 0.0, 2.0, 4.0, 6.0,
# 8.0, 10.0, 12.0, 14.0,
# 16.0, 18.0, 20.0, 22.0]
a*a
#[ 0.0, 1.0, 4.0, 9.0,
# 16.0, 25.0, 36.0, 49.0,
# 64.0, 81.0, 100.0, 121.0]
a[8::-1]
#[8.0, 7.0, 6.0, 5.0,
# 4.0, 3.0, 2.0, 1.0,
# 0.0]
# It even resists reshaping
b=a.reshape((3,4))
b
#MyArr([[ 0., 1., 2., 3.],
# [ 4., 5., 6., 7.],
# [ 8., 9., 10., 11.]])
b.reshape((12,))
#[ 0.0, 1.0, 2.0, 3.0,
# 4.0, 5.0, 6.0, 7.0,
# 8.0, 9.0, 10.0, 11.0]
# Or fancy indexing
a[np.array([1,2,5,5,5])]
#[1.0, 2.0, 5.0, 5.0,
# 5.0]
# Or matrix operations
M=np.eye(12,k=1)+2*M.identity(12) # Just a matrix
M@a
#[ 1.0, 4.0, 7.0, 10.0,
# 13.0, 16.0, 19.0, 22.0,
# 25.0, 28.0, 31.0, 22.0]
np.diag(M*a)
#[ 0.0, 2.0, 4.0, 6.0,
# 8.0, 10.0, 12.0, 14.0,
# 16.0, 18.0, 20.0, 22.0]
# But of course, some time you loose the MyArr class
import pandas as pd
pd.DataFrame(a, columns=['v']).v.values
#array([ 0., 1., 2., 3., 4., 5., 6., 7., 8., 9., 10., 11.])
[1]: https://stackoverflow.com/questions/25991666/how-to-efficiently-output-n-items-per-line-from-numpy-array