第八章:NumPy 数组的形状操作 第八章:NumPy 数组的形状操作 8.1 改变数组形状 NumPy 提供了多种方法来改变数组的形状,而无需修改其数据。 8.1.1 函数 函数允许我们在不改变数组数据的情况下,改变数组的维度。 输出: 注意: 返回的是一个视图(view),这意味着它与原始数组共享数据。修改 reshape 后的数组可能会影响原始数组。如果需要一个独立的副本,可以使用 方法。 8.1.2 函数 函数与 类似,但它会直接修改原始数组。 输出: 8.1.3 和 函数 这两个函数都可以将多维数组转换为一维数组。 返回一个副本,修改副本不会影响原始数组。 返回一个视图,修改视图可能会影响原始数组。 输出: 8.1.4 函数和 属性 函数和 属性用于交换数组的维度。
NumPy 提供了多种方法来改变数组的形状,而无需修改其数据。
8.1.1 reshape() 函数
reshape() 函数允许我们在不改变数组数据的情况下,改变数组的维度。
import numpy as np arr = np.arange(12) print("原始数组:", arr) # 改变为 3x4 的二维数组 reshaped_arr = arr.reshape(3, 4) print("reshape后的数组:\n", reshaped_arr) # 改变为 2x2x3 的三维数组 reshaped_arr_3d = arr.reshape(2, 2, 3) print("reshape后的三维数组:\n", reshaped_arr_3d)
输出:
原始数组: [ 0 1 2 3 4 5 6 7 8 9 10 11] reshape后的数组: [[ 0 1 2 3] [ 4 5 6 7] [ 8 9 10 11]] reshape后的三维数组: [[[ 0 1 2] [ 3 4 5]] [[ 6 7 8] [ 9 10 11]]]
注意: reshape() 返回的是一个视图(view),这意味着它与原始数组共享数据。修改 reshape 后的数组可能会影响原始数组。如果需要一个独立的副本,可以使用 copy() 方法。
8.1.2 resize() 函数
resize() 函数与 reshape() 类似,但它会直接修改原始数组。
arr = np.arange(6) print("原始数组:", arr) # 改变数组形状并修改原始数组 arr.resize(2, 3) print("resize后的数组:\n", arr) # 如果新的尺寸大于原始数组,则用 0 填充 arr.resize(3, 3) print("resize后的数组(填充 0):\n", arr)
输出:
原始数组: [0 1 2 3 4 5] resize后的数组: [[0 1 2] [3 4 5]] resize后的数组(填充 0): [[0 1 2] [3 4 5] [0 0 0]]
8.1.3 flatten() 和 ravel() 函数
这两个函数都可以将多维数组转换为一维数组。
flatten() 返回一个副本,修改副本不会影响原始数组。
ravel() 返回一个视图,修改视图可能会影响原始数组。
arr = np.array([[1, 2], [3, 4]]) print("原始数组:\n", arr) # flatten() flattened_arr = arr.flatten() print("flattened数组:", flattened_arr) # ravel() raveled_arr = arr.ravel() print("raveled数组:", raveled_arr) # 修改 raveled 数组 raveled_arr[0] = 100 print("修改后的 raveled 数组:", raveled_arr) print("原始数组(已受影响):\n", arr)
输出:
原始数组: [[1 2] [3 4]] flattened数组: [1 2 3 4] raveled数组: [1 2 3 4] 修改后的 raveled 数组: [100 2 3 4] 原始数组(已受影响): [[100 2] [ 3 4]]
8.1.4 transpose() 函数和 .T 属性
transpose() 函数和 .T 属性用于交换数组的维度。对于二维数组,这相当于转置矩阵。
arr = np.array([[1, 2, 3], [4, 5, 6]]) print("原始数组:\n", arr) # 使用 transpose() transposed_arr = arr.transpose() print("转置后的数组:\n", transposed_arr) # 使用 .T 属性 transposed_arr_T = arr.T print("使用 .T 属性转置后的数组:\n", transposed_arr_T)
输出:
原始数组: [[1 2 3] [4 5 6]] 转置后的数组: [[1 4] [2 5] [3 6]] 使用 .T 属性转置后的数组: [[1 4] [2 5] [3 6]]
8.1.5 swapaxes() 函数
swapaxes() 函数用于交换数组的两个轴。
arr = np.arange(24).reshape((2, 3, 4)) print("原始数组:\n", arr) # 交换 0 轴和 1 轴 swapped_arr = np.swapaxes(arr, 0, 1) print("交换轴后的数组:\n", swapped_arr)
输出:
原始数组: [[[ 0 1 2 3] [ 4 5 6 7] [ 8 9 10 11]] [[12 13 14 15] [16 17 18 19] [20 21 22 23]]] 交换轴后的数组: [[[ 0 1 2 3] [12 13 14 15]] [[ 4 5 6 7] [16 17 18 19]] [[ 8 9 10 11] [20 21 22 23]]]
NumPy 提供了多种函数来组合数组。
8.2.1 concatenate() 函数
concatenate() 函数用于沿指定的轴连接数组。
arr1 = np.array([[1, 2], [3, 4]]) arr2 = np.array([[5, 6], [7, 8]]) # 沿 0 轴连接 (垂直方向) concatenated_arr_axis0 = np.concatenate((arr1, arr2), axis=0) print("沿 0 轴连接:\n", concatenated_arr_axis0) # 沿 1 轴连接 (水平方向) concatenated_arr_axis1 = np.concatenate((arr1, arr2), axis=1) print("沿 1 轴连接:\n", concatenated_arr_axis1)
输出:
沿 0 轴连接: [[1 2] [3 4] [5 6] [7 8]] 沿 1 轴连接: [[1 2 5 6] [3 4 7 8]]
8.2.2 stack() 函数
stack() 函数沿着新的轴连接数组。
arr1 = np.array([1, 2, 3]) arr2 = np.array([4, 5, 6]) # 沿新的 0 轴堆叠 stacked_arr_axis0 = np.stack((arr1, arr2), axis=0) print("沿新的 0 轴堆叠:\n", stacked_arr_axis0) # 沿新的 1 轴堆叠 stacked_arr_axis1 = np.stack((arr1, arr2), axis=1) print("沿新的 1 轴堆叠:\n", stacked_arr_axis1)
输出:
沿新的 0 轴堆叠: [[1 2 3] [4 5 6]] 沿新的 1 轴堆叠: [[1 4] [2 5] [3 6]]
8.2.3 hstack() 和 vstack() 函数
hstack() 和 vstack() 函数分别是 concatenate() 函数在水平和垂直方向上的简写。
arr1 = np.array([1, 2, 3]) arr2 = np.array([4, 5, 6]) # 水平堆叠 hstack_arr = np.hstack((arr1, arr2)) print("水平堆叠:", hstack_arr) # 垂直堆叠 vstack_arr = np.vstack((arr1, arr2)) print("垂直堆叠:\n", vstack_arr)
输出:
水平堆叠: [1 2 3 4 5 6] 垂直堆叠: [[1 2 3] [4 5 6]]
8.2.4 dstack() 函数
dstack() 函数沿着深度方向堆叠数组(第三个轴)。
arr1 = np.array([1, 2, 3]) arr2 = np.array([4, 5, 6]) # 深度堆叠 dstack_arr = np.dstack((arr1, arr2)) print("深度堆叠:\n", dstack_arr)
输出:
深度堆叠: [[[1 4] [2 5] [3 6]]]
NumPy 提供了多种函数来分割数组。
8.3.1 split() 函数
split() 函数用于将数组分割成多个子数组。
arr = np.arange(12) # 分割成 3 个子数组 split_arr = np.split(arr, 3) print("分割成 3 个子数组:", split_arr) # 分割成不均匀的子数组 split_arr_uneven = np.split(arr, [2, 5, 8]) print("分割成不均匀的子数组:", split_arr_uneven)
输出:
分割成 3 个子数组: [array([0, 1, 2, 3]), array([4, 5, 6, 7]), array([ 8, 9, 10, 11])] 分割成不均匀的子数组: [array([0, 1]), array([2, 3, 4]), array([5, 6, 7]), array([ 8, 9, 10, 11])]
8.3.2 hsplit() 和 vsplit() 函数
hsplit() 和 vsplit() 函数分别是 split() 函数在水平和垂直方向上的简写。
arr = np.array([[1, 2, 3, 4], [5, 6, 7, 8], [9, 10, 11, 12]]) # 水平分割 hsplit_arr = np.hsplit(arr, 2) print("水平分割:\n", hsplit_arr) # 垂直分割 vsplit_arr = np.vsplit(arr, 3) print("垂直分割:\n", vsplit_arr)
输出:
水平分割: [array([[ 1, 2], [ 5, 6], [ 9, 10]]), array([[ 3, 4], [ 7, 8], [11, 12]])] 垂直分割: [array([[1, 2, 3, 4]]), array([[5, 6, 7, 8]]), array([[ 9, 10, 11, 12]])]
8.3.3 dsplit() 函数
dsplit() 函数沿着深度方向分割数组(第三个轴)。
arr = np.arange(27).reshape(3, 3, 3) # 深度分割 dsplit_arr = np.dsplit(arr, 3) print("深度分割:\n", dsplit_arr)
输出:
深度分割: [array([[[ 0], [ 9], [18]], [[ 3], [12], [21]], [[ 6], [15], [24]]]), array([[[ 1], [10], [19]], [[ 4], [13], [22]], [[ 7], [16], [25]]]), array([[[ 2], [11], [20]], [[ 5], [14], [23]], [[ 8], [17], [26]]])]
8.4.1 expand_dims() 函数
expand_dims() 函数用于在指定的轴上添加一个维度。
arr = np.array([1, 2, 3]) # 在 0 轴上添加维度 expanded_arr_axis0 = np.expand_dims(arr, axis=0) print("在 0 轴上添加维度:", expanded_arr_axis0) # 在 1 轴上添加维度 expanded_arr_axis1 = np.expand_dims(arr, axis=1) print("在 1 轴上添加维度:\n", expanded_arr_axis1)
输出:
在 0 轴上添加维度: [[1 2 3]] 在 1 轴上添加维度: [[1] [2] [3]]
8.4.2 squeeze() 函数
squeeze() 函数用于删除长度为 1 的维度。
arr = np.array([[[1, 2, 3]]]) # 删除长度为 1 的维度 squeezed_arr = np.squeeze(arr) print("删除维度后的数组:", squeezed_arr) arr = np.array([[[1], [2], [3]]]) squeezed_arr = np.squeeze(arr, axis = 2) # 删除指定轴上的维度 print("删除指定轴上的维度:", squeezed_arr)
输出:
删除维度后的数组: [1 2 3] 删除指定轴上的维度: [[1] [2] [3]]
本章介绍了 NumPy 数组的各种形状操作,包括改变形状、组合数组、分割数组以及添加和删除维度。掌握这些操作对于数据处理和分析至关重要。通过灵活运用这些函数,可以更高效地处理各种数据,并为后续的算法实现和可视化打下坚实的基础。
以下是一个简单的 Mermaid 图表,展示了 reshape() 函数的使用:
这个图表描述了如何使用 reshape() 函数将一个原始数组转换为一个 3x4 的数组。
希望本章内容对您有所帮助!