如何在 Python 中重塑 NumPy 数组

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

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

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

什么是 NumPy 数组中的重塑?

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

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

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

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

▶️ 要按照本教程中的示例进行操作,您需要安装 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”根据数组 arr 的内存布局以类似 C 或类似 Fortran 的顺序读取元素。

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

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

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

查看与 NumPy 数组的副本

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

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

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

#1。 让我们首先使用创建示例数组 np.arange().

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

  5 个 Xposed 模块调整 Google 音乐、通知、锁定屏幕

现在让我们使用上面的语法,将具有 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]]

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

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

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

让我们快速验证这一点。

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

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

  如何将您的 Google Home Hub 用作数码相框

#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)

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

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_arr 和 flat_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 替代品指南。