8.2 数组的展平 (Flattening) NumPy 数组的展平 (Flattening) 在 NumPy 中,数组的展平 (Flattening) 指的是将一个多维数组转换为一个一维数组的过程。这在许多数据处理和机器学习任务中非常常见,例如将图像数据输入到全连接神经网络,或者在进行某些统计计算之前。NumPy 提供了多种方法来实现数组的展平,每种方法都有其独特的特性和适用场景。 8.2.1 方法 是 NumPy 数组对象的一个方法,它会返回一个新的一维数组,其中包含了原始数组的所有元素,按照行优先 (row-major) 的顺序排列。这意味着它会按照数组的行依次将元素添加到新数组中。 语法: 参数: (可选): 指定展平的顺序。
在 NumPy 中,数组的展平 (Flattening) 指的是将一个多维数组转换为一个一维数组的过程。这在许多数据处理和机器学习任务中非常常见,例如将图像数据输入到全连接神经网络,或者在进行某些统计计算之前。NumPy 提供了多种方法来实现数组的展平,每种方法都有其独特的特性和适用场景。
flatten() 方法flatten() 是 NumPy 数组对象的一个方法,它会返回一个新的一维数组,其中包含了原始数组的所有元素,按照行优先 (row-major) 的顺序排列。这意味着它会按照数组的行依次将元素添加到新数组中。
语法:
ndarray.flatten(order='C')
参数:
order (可选): 指定展平的顺序。可以是以下值:
'C' (默认): 行优先 (C-style) 顺序。
'F' : 列优先 (Fortran-style) 顺序。
'A' : 如果 a 在内存中是 Fortran 连续的,则按列优先顺序展平;否则,按行优先顺序展平。
'K' : 按照元素在内存中出现的顺序展平,保留数据布局。
代码示例:
import numpy as np # 创建一个 2x3 的二维数组 arr = np.array([[1, 2, 3], [4, 5, 6]]) print("原始数组:\n", arr) # 使用 flatten() 方法展平数组 flattened_arr = arr.flatten() print("\n展平后的数组:\n", flattened_arr) # 使用 flatten(order='F') 方法按列优先顺序展平数组 flattened_arr_F = arr.flatten(order='F') print("\n按列优先顺序展平后的数组:\n", flattened_arr_F)
输出:
原始数组: [[1 2 3] [4 5 6]] 展平后的数组: [1 2 3 4 5 6] 按列优先顺序展平后的数组: [1 4 2 5 3 6]
详解:
arr.flatten() 创建了一个新的数组 flattened_arr,其中包含了 arr 的所有元素,按照行优先的顺序排列。
arr.flatten(order='F') 创建了一个新的数组 flattened_arr_F,其中包含了 arr 的所有元素,按照列优先的顺序排列。
优点:
简单易用。
可以指定展平的顺序。
缺点:
会创建一个新的数组,占用额外的内存。 如果原始数组很大,这可能会成为一个问题。
修改展平后的数组不会影响原始数组。
ravel() 函数ravel() 是 NumPy 库中的一个函数,它也可以将多维数组转换为一维数组。与 flatten() 不同的是,ravel() 尝试返回原始数组的视图 (view),这意味着它不会复制数据,而是返回一个指向原始数组数据的新的数组对象。如果无法返回视图(例如,如果数组在内存中不是连续的),ravel() 会复制数据。
语法:
numpy.ravel(a, order='C')
参数:
a : 要展平的数组。
order (可选): 指定展平的顺序。可以是以下值:
'C' (默认): 行优先 (C-style) 顺序。
'F' : 列优先 (Fortran-style) 顺序。
'A' : 如果 a 在内存中是 Fortran 连续的,则按列优先顺序展平;否则,按行优先顺序展平。
'K' : 按照元素在内存中出现的顺序展平,保留数据布局。
代码示例:
import numpy as np # 创建一个 2x3 的二维数组 arr = np.array([[1, 2, 3], [4, 5, 6]]) print("原始数组:\n", arr) # 使用 ravel() 函数展平数组 raveled_arr = np.ravel(arr) print("\n展平后的数组:\n", raveled_arr) # 修改展平后的数组 raveled_arr[0] = 10 # 检查原始数组是否被修改 print("\n修改后的原始数组:\n", arr) # 使用 ravel(order='F') 函数按列优先顺序展平数组 raveled_arr_F = np.ravel(arr, order='F') print("\n按列优先顺序展平后的数组:\n", raveled_arr_F)
输出:
原始数组: [[1 2 3] [4 5 6]] 展平后的数组: [1 2 3 4 5 6] 修改后的原始数组: [[10 2 3] [ 4 5 6]] 按列优先顺序展平后的数组: [10 4 2 5 3 6]
详解:
np.ravel(arr) 返回一个 raveled_arr,它是 arr 的一个视图。这意味着 raveled_arr 和 arr 共享相同的数据。
修改 raveled_arr 的元素会影响 arr 的对应元素。
np.ravel(arr, order='F') 返回一个按列优先顺序展平的数组。
优点:
如果返回的是视图,则不会复制数据,节省内存。
修改展平后的数组可能会影响原始数组,这在某些情况下很有用。
缺点:
修改展平后的数组可能会影响原始数组,这在某些情况下可能不希望发生。
不保证总是返回视图,如果数组在内存中不是连续的,则会复制数据。
reshape() 函数reshape() 函数主要用于改变数组的形状,但它也可以用来将多维数组转换为一维数组。通过将目标形状设置为 (-1,),可以让 NumPy 自动计算一维数组的长度。
语法:
ndarray.reshape(shape, order='C')
参数:
shape : 新的形状。对于展平操作,设置为 (-1,)。
order (可选): 指定重塑的顺序。可以是以下值:
'C' (默认): 行优先 (C-style) 顺序。
'F' : 列优先 (Fortran-style) 顺序。
'A' : 如果 a 在内存中是 Fortran 连续的,则按列优先顺序重塑;否则,按行优先顺序重塑。
代码示例:
import numpy as np # 创建一个 2x3 的二维数组 arr = np.array([[1, 2, 3], [4, 5, 6]]) print("原始数组:\n", arr) # 使用 reshape() 函数展平数组 reshaped_arr = arr.reshape(-1) print("\n展平后的数组:\n", reshaped_arr) # 修改展平后的数组 reshaped_arr[0] = 10 # 检查原始数组是否被修改 print("\n修改后的原始数组:\n", arr) # 使用 reshape(order='F') 函数按列优先顺序展平数组 reshaped_arr_F = arr.reshape(-1, order='F') print("\n按列优先顺序展平后的数组:\n", reshaped_arr_F)
输出:
原始数组: [[1 2 3] [4 5 6]] 展平后的数组: [1 2 3 4 5 6] 修改后的原始数组: [[10 2 3] [ 4 5 6]] 按列优先顺序展平后的数组: [10 4 2 5 3 6]
详解:
arr.reshape(-1) 返回一个 reshaped_arr,它是 arr 的一个视图。这意味着 reshaped_arr 和 arr 共享相同的数据。
修改 reshaped_arr 的元素会影响 arr 的对应元素。
arr.reshape(-1, order='F') 返回一个按列优先顺序重塑的数组。
优点:
如果返回的是视图,则不会复制数据,节省内存。
修改展平后的数组可能会影响原始数组,这在某些情况下很有用。
语法简洁。
缺点:
修改展平后的数组可能会影响原始数组,这在某些情况下可能不希望发生。
不保证总是返回视图,如果数组在内存中不是连续的,则会复制数据。
选择哪种方法取决于你的具体需求:
如果需要创建一个新的数组,并且不希望修改原始数组,则使用 flatten()。
如果希望尽可能节省内存,并且可以接受修改原始数组的风险,则使用 ravel() 或 reshape()。
如果需要按列优先顺序展平数组,则可以在 flatten()、ravel() 或 reshape() 中使用 order='F' 参数。
NumPy 提供了多种方法来展平数组,每种方法都有其独特的特性。理解这些方法的差异可以帮助你选择最适合你需求的工具。
总而言之,flatten() 创建副本,ravel() 和 reshape() 尝试创建视图。 根据具体的使用场景和对内存以及数据修改的需求,选择合适的方法进行数组的展平操作。