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

在本教程中,您将学习如何使用NumPy reshape()来重塑NumPy数组,而不改变原始数据。

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

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

NumPy数组中的重塑是什么?

在使用NumPy数组时,您可能首先希望创建一个由数字组成的一维数组。然后将其重塑为具有所需维度的数组。

当新数组的维度在初始时未知或在执行过程中推断出时,这特别有帮助。或者可能在某些数据处理步骤中需要输入具有特定形状。

这就是重塑的用处。

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

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

您现在可以继续导入别名为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数组的视图与副本

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

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

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

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

我们需要一个由12个数字组成的数组,从1到12,称为arr1。由于NumPy的arange()函数默认情况下排除终点,所以将停止值设置为13。

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

import numpy as np

arr1 = np.arange(1,13)
print("原始数组,重塑之前:n")
print(arr1)

# 重塑数组
arr2 = np.reshape(arr1,(4,3))
print("n重塑后的数组:")
print(arr2)

让我们来看看原始数组和重塑后的数组。

原始数组,重塑之前:

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

重塑后的数组:
[[ 1  2  3]
 [ 4  5  6]
 [ 7  8  9]
 [10 11 12]]

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

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

dir(arr1)

# 输出
[
...
...
'reshape'
...
..
]

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

▶️ 因此,您也可以使用以下简化的语法来重塑NumPy数组。

arr.reshape(d0,d1,...,dn)

# 其中:

# d0,d1,..,dn是重塑数组的维度

# d0 * d1 * ...* dn = N,arr中的元素数

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

#2. 让我们将包含12个元素的向量重塑为12 x 1数组。

import numpy as np

arr1 = np.arange(1,13)
print("原始数组,重塑之前:n")
print(arr1)

# 重塑数组
arr3 = arr1.reshape(12,1)
print("n重塑后的数组:")
print(arr3)

在下面的输出中,您可以看到数组已按需要重塑。

原始数组,重塑之前:

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

重塑后的数组:
[[ 1]
 [ 2]
 [ 3]
 [ 4]
 [ 5]
 [ 6]
 [ 7]
 [ 8]
 [ 9]
 [10]
 [11]
 [12]]

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

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

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

让我们快速验证一下。

arr3.base
# 输出
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("原始数组,重塑之前:n")
print(arr1)

# 重塑数组
arr4 = arr1.reshape(2,6)
print("n重塑后的数组:")
print(arr4)

以下是输出:

原始数组,重塑之前:

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

重塑后的数组:
[[ 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("原始数组,重塑之前:n")
print(arr1)

# 重塑数组
arr3D = arr1.reshape(1,4,3)
print("n重塑后的数组:")
print(arr3D)

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

原始数组,重塑之前:

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

重塑后的数组:
[[[ 1  2  3]
  [ 4  5  6]
  [ 7  8  9]
  [10 11 12]]]

如何在调整形状过程中调试值错误

如果你记得语法,只有当维数的乘积等于数组中的元素数量时,调整形状才有效。

import numpy as np

arr1 = np.arange(1,13)
print("调整形状之前的原始数组:n")
print(arr1)

# 调整形状数组
arr2D = arr1.reshape(4,4)
print("n调整形状后的数组:")
print(arr2D)

在这个例子中,你尝试将一个有12个元素的数组调整为一个有16个元素的4×4数组。解释器抛出了一个值错误,如下所示。

调整形状之前的原始数组:

[ 1  2  3  4  5  6  7  8  9 10 11 12]
-----------------------------------------------------------
ValueError                                
Traceback (most recent call last)
 in ()
      6 
      7 # 调整形状数组
----> 8 arr2 = arr1.reshape(4,4)
      9 print("n调整形状后的数组:")
     10 print(arr2)

ValueError: 无法将大小为12的数组调整为形状(4,4)

为了避免这样的错误,你可以使用-1自动推断出一个维度的形状 – 基于元素的总数量。

例如,如果你事先知道 n – 1 个维度,你可以使用 -1 推断出调整形状数组中的第 n 个维度。

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

import numpy as np

arr1 = np.arange(1,25)
print("调整形状之前的原始数组:n")
print(arr1)

# 调整形状数组
arr_res = arr1.reshape(4,3,-1)
print("n调整形状后的数组:")
print(arr_res)
print(f"arr_res的形状:{arr_res.shape}")

当你检查形状数组的形状时,你会发现调整形状后的数组在第三个维度上具有形状为2。

调整形状之前的原始数组:

[ 1  2  3  4  5  6  7  8  9 10 11 12 
13 14 15 16 17 18 19 20 21 22 23 24]

调整形状后的数组:
[[[ 1  2]
  [ 3  4]
  [ 5  6]]

 [[ 7  8]
  [ 9 10]
  [11 12]]

 [[13 14]
  [15 16]
  [17 18]]

 [[19 20]
  [21 22]
  [23 24]]]
arr_res的形状:(4, 3, 2)

这在展开数组时特别有用。你将在下一节中学到相关内容。

使用NumPy的reshape()函数展开数组

有时候你需要将N维数组展开为一个平坦的数组。假设你想将图像展开为一个像素的长向量。

让我们通过以下步骤编写一个简单的例子来演示:

  • 生成一个3×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"img_arr的形状:{img_arr.shape}")
flat_arr = img_arr.reshape(-1)
print(flat_arr)
print(f"flat_arr的形状:{flat_arr.shape}")

下面是输出结果。

[[195 145  77]
 [ 63 193 223]
 [215  43  36]]
img_arr的形状:(3, 3)

[195 145  77  63 193 223 215  43  36]
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 alternatives指南。

类似文章