NumPy reshape():如何在 Python 中重塑 NumPy 数组

已发表: 2022-04-20

在本教程中,您将学习如何使用NumPy reshape()在不更改原始数据的情况下重塑 NumPy 数组。

使用 Numpy 数组时,您可能经常希望将现有数组重塑为不同维度的数组。 当您在多个步骤中转换数据时,这可能特别有用。

NumPy reshape()可以帮助您轻松完成。 在接下来的几分钟内,您将学习使用reshape()的语法,并将数组重塑为不同的维度。

什么是 NumPy 数组中的重塑?

使用 NumPy 数组时,您可能首先要创建一个一维数字数组。 然后将其重塑为具有所需尺寸的数组。

当新数组的维度最初未知或在执行期间推断时,这特别有用。 或者,某个数据处理步骤也可能要求输入具有特定形状。

这就是重塑派上用场的地方。

例如,考虑下图。 我们有一个向量——一个由 6 个元素组成的一维数组。 我们可以将其重塑为 2×3、3×2、6×1 等形状的数组。

numpy 重塑

️ 要按照本教程中的示例进行操作,您需要安装 Python 和 NumPy。 如果您还没有 NumPy,请查看我们的 NumPy 安装指南。

您现在可以继续并在别名np下导入 NumPy,方法是运行: import numpy as np

让我们继续学习下一节中的语法。

NumPy reshape() 的语法

下面是使用 NumPy reshape() 的语法:

 np.reshape(arr, newshape, order = 'C'|'F'|'A')
  • arr是任何有效的 NumPy 数组对象。 在这里,它是要重塑的阵列。
  • newshape是新数组的形状。 它可以是整数或元组。
  • newshape为整数时,返回的数组是一维的。
  • order是指您希望读取要重新整形的数组元素的顺序。
  • 默认值为'C',这意味着原始数组的元素将以类似C的索引顺序(从0开始)读取
  • “F”代表类似 Fortran 的索引(从 1 开始)。 'A'以类似 C 或类似 Fortran 的顺序读取元素,具体取决于数组arr的内存布局。

那么np.reshape()返回什么?

如果可能,它会返回原始数组的重塑视图。 否则,它会返回数组的副本

在上面一行中,我们提到 NumPy reshape()会尽可能尝试返回视图。 否则,它返回一个副本。 让我们继续讨论视图和副本之间的区别。

查看与 NumPy 数组的副本

顾名思义, copy是原始数组的副本。 对副本所做的任何更改都不会影响原始数组。

另一方面,视图只是指原始阵列的重塑视图。 这意味着对视图所做的任何更改也会影响原始数组,反之亦然。

使用 NumPy reshape() 将一维数组重塑为二维数组

#1。 让我们从使用 np.arange() 创建示例数组开始。

我们需要一个包含 12 个数字的数组,从 1 到 12,称为 arr1。 由于 NumPy arange() 函数默认不包括端点,因此将停止值设置为 13。

现在让我们使用上面的语法,将具有 12 个元素的arr1重塑为形状为 (4,3) 的二维数组。 让我们将此arr2称为 4 行 3 列。

 import numpy as np arr1 = np.arange(1,13) print("Original array, before reshaping:\n") print(arr1) # Reshape array arr2 = np.reshape(arr1,(4,3)) print("\nReshaped array:") print(arr2)

让我们看一下原始数组和重构数组。

 Original array, before reshaping: [ 1 2 3 4 5 6 7 8 9 10 11 12] Reshaped array: [[ 1 2 3] [ 4 5 6] [ 7 8 9] [10 11 12]]

除了将数组作为参数np.reshape() ,您还可以在原始数组上调用.reshape()方法。

您可以运行dir(arr1) ,它将列出您可以在数组对象arr1上使用的所有可能的方法和属性。

 dir(arr1) # Output [ ... ... 'reshape' ... .. ]

在上面的代码单元中,您可以看到.reshape()是在现有 NumPy 数组arr1上使用的有效方法。

️ 所以,你也可以使用下面的简化语法来重塑 NumPy 数组。

 arr.reshape(d0,d1,...,dn) # where: # d0, d1,..,dn are the dimensions of the reshaped array # d0 * d1 * ...* dn = N, the number of elements in arr

对于本教程的其余部分,让我们在示例中使用此语法。

#2。 让我们尝试将我们的 12 元素向量重塑为 12 x 1 数组。

 import numpy as np arr1 = np.arange(1,13) print("Original array, before reshaping:\n") print(arr1) # Reshape array arr3 = arr1.reshape(12,1) print("\nReshaped array:") print(arr3)

在下面的输出中,您可以看到数组已根据需要进行了重新整形。

 Original array, before reshaping: [ 1 2 3 4 5 6 7 8 9 10 11 12] Reshaped array: [[ 1] [ 2] [ 3] [ 4] [ 5] [ 6] [ 7] [ 8] [ 9] [10] [11] [12]]

那么,我们如何检查我们是否获得了副本或视图?

要检查这一点,您可以调用返回数组的base属性。

  • 如果数组是副本,则base属性将为None
  • 如果数组是视图,则base属性将是原始数组。

让我们快速验证这一点。

 arr3.base # Output array([ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12])

如您所见, arr3base属性返回原始数组。 这意味着我们已经收到了原始数组的视图

#3。 现在,让我们尝试将向量重塑为另一个有效的 2 x 6 数组。

 import numpy as np arr1 = np.arange(1,13) print("Original array, before reshaping:\n") print(arr1) # Reshape array arr4 = arr1.reshape(2,6) print("\nReshaped array:") print(arr4)

这是输出:

 Original array, before reshaping: [ 1 2 3 4 5 6 7 8 9 10 11 12] Reshaped array: [[ 1 2 3 4 5 6] [ 7 8 9 10 11 12]]

在下一节中,让我们将arr1重塑为 3D 数组。

使用 NumPy reshape() 将 1D 数组重塑为 3D 数组

要将arr1重塑为 3D 数组,让我们将所需的维度设置为 (1, 4, 3)。

 import numpy as np arr1 = np.arange(1,13) print("Original array, before reshaping:\n") print(arr1) # Reshape array arr3D = arr1.reshape(1,4,3) print("\nReshaped array:") print(arr3D)

我们现在已经创建了一个 3D 数组,它具有与原始数组arr1相同的 12 个元素。

 Original array, before reshaping: [ 1 2 3 4 5 6 7 8 9 10 11 12] Reshaped array: [[[ 1 2 3] [ 4 5 6] [ 7 8 9] [10 11 12]]]

如何在重塑期间调试值错误

如果您还记得语法,那么仅当维度的乘积等于数组中元素的数量时,整形才有效。

 import numpy as np arr1 = np.arange(1,13) print("Original array, before reshaping:\n") print(arr1) # Reshape array arr2D = arr1.reshape(4,4) print("\nReshaped array:") print(arr2D)

在这里,您尝试将一个 12 元素数组重塑为一个 4×4 数组,其中包含 16 个元素。 解释器抛出一个值错误,如下所示。

 Original array, before reshaping: [ 1 2 3 4 5 6 7 8 9 10 11 12] ----------------------------------------------------------- ValueError Traceback (most recent call last) <ipython-input-11-63552bcc8c37> in <module>() 6 7 # Reshape array ----> 8 arr2 = arr1.reshape(4,4) 9 print("\nReshaped array:") 10 print(arr2) ValueError: cannot reshape array of size 12 into shape (4,4)

为避免此类错误,您可以使用-1根据元素总数自动推断其中一个维度的形状。

例如,如果您事先知道 n – 1 个维度,则可以使用 -1 来推断重构数组中的第 n 个维度。

如果您有一个 24 元素的数组,并且您想将其重塑为 3D 数组。 假设您需要 3 行和 4 列。 您可以沿第三个维度传入 -1 的值。

 import numpy as np arr1 = np.arange(1,25) print("Original array, before reshaping:\n") print(arr1) # Reshape array arr_res = arr1.reshape(4,3,-1) print("\nReshaped array:") print(arr_res) print(f"Shape of arr_res:{arr_res.shape}")

当您检查形状数组的形状时,您可以看到重新调整的数组沿第三维的形状为 2。

 Original array, before reshaping: [ 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24] Reshaped array: [[[ 1 2] [ 3 4] [ 5 6]] [[ 7 8] [ 9 10] [11 12]] [[13 14] [15 16] [17 18]] [[19 20] [21 22] [23 24]]] Shape of arr_res:(4, 3, 2)

这对于展平阵列特别有用。 您将在下一节中了解这一点。

使用 NumPy reshape() 展平数组

有时您需要从 N 维数组返回到扁平数组。 假设您要将图像展平为一个长的像素向量。

让我们使用以下步骤编写一个简单的示例:

  • 生成一个 3 x 3 灰度图像数组img_arr — 像素范围为 0 到 255。
  • 接下来,展平这个img_arr并打印出展平的数组flat_arr
  • 另外,打印出img_arrflat_arr的形状进行验证。
 img_arr = np.random.randint(0, 255, (3,3)) print(img_arr) print(f"Shape of img_arr: {img_arr.shape}") flat_arr = img_arr.reshape(-1) print(flat_arr) print(f"Shape of flat_arr: {flat_arr.shape}")

这是输出。

 [[195 145 77] [ 63 193 223] [215 43 36]] Shape of img_arr: (3, 3) [195 145 77 63 193 223 215 43 36] Shape of flat_arr: (9,)

在上面的代码单元中,您可以看到flat_arr是具有 9 个元素的像素值的一维向量。

加起来

是时候快速回顾一下我们学到的东西了。

  • 使用np.reshape(arr, newshape)arr重塑为newshape中指定的形状。 newshape是一个元组,指定了重构数组的维度。
  • 或者,使用arr.reshape(d0, d1, ..., dn)arr重塑为形状d0 x d1 x ... x dn
  • 检查是否d0 * d1 * …* dn = N ,原始数组中的元素数,以避免在整形期间出现值错误。
  • 如果您希望自动推断维度,则对新形状中的最多一个维度使用-1
  • 最后,您可以使用arr.reshape(-1)来展平阵列。

现在您知道如何使用 NumPy reshape(),了解 NumPy linspace() 函数的工作原理。

如果您愿意,可以尝试 Jupyter notebook 中的代码示例。 如果您正在寻找其他开发环境,请查看我们的 Jupyter 替代品指南。