带有余数的 Numpy 重塑会抛出错误

Numpy reshape with remainder throws error

如何将这个数组划分为长度为 3 的数组,余数是填充的还是未填充的(无关紧要)

>>> np.array([0,1,2,3,4,5,6,7,8,9,10]).reshape([3,-1])

ValueError: cannot reshape array of size 11 into shape (3,newaxis)

### Two Examples Without Padding

x = np.array([0,1,2,3,4,5,6,7,8,9,10])
desired_length = 3
num_splits = np.ceil(x.shape[0]/desired_length)

print(np.array_split(x, num_splits))

# Prints:
# [array([0, 1, 2]), array([3, 4, 5]), array([6, 7, 8]), array([ 9, 10])]

x = np.arange(13)
desired_length = 3
num_splits = np.ceil(x.shape[0]/desired_length)

print(np.array_split(x, num_splits))

# Prints:
# [array([0, 1, 2]), array([3, 4, 5]), array([6, 7, 8]), array([ 9, 10]), array([11, 12])]

### One Example With Padding

x = np.arange(13)
desired_length = 3
padding = int(num_splits*desired_length - x.shape[0])
x_pad = np.pad(x, (0,padding), 'constant', constant_values=0)

print(np.split(x_pad, num_splits))

# Prints:
# [array([0, 1, 2]), array([3, 4, 5]), array([6, 7, 8]), array([ 9, 10, 11]), array([12,  0,  0])]

如果您想用零填充,ndarray.resize() 会为您完成此操作,但您必须自己计算出预期数组的大小:

import numpy as np

x = np.array([0,1,2,3,4,5,6,7,8,9,10])

cols = 3
rows = np.ceil(x.size / cols).astype(int)

x.resize((rows, cols))
print(x)

这导致:

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

据我所知,这比列表理解方法快数百倍(请参阅我的其他答案)。

请注意,如果您在调整大小之前对 x 执行任何操作,您可能 运行 会遇到 'references' 的问题。要么在 x.copy() 上工作,要么将 refcheck=False 传递给 resize()

如果你想避免用零填充,最优雅的方法可能是在列表理解中切片:

>>> import numpy as np
>>> x = np.arange(11)
>>> [x[i:i+3] for i in range(0, x.size, 3)]
[array([0, 1, 2]), array([3, 4, 5]), array([6, 7, 8]), array([ 9, 10])]