机器学习之ravel()的作用

ravel() 是 NumPy 中一个非常实用但也容易与其他函数混淆的函数。

numpy.ravel() 的核心作用

ravel() 的核心作用非常简单:将一个任意维度的 NumPy 数组"压平"(flatten),变成一个一维数组。

可以把它想象成"解开"或"铺平"一个多维数组。无论你给它的是一个二维矩阵、三维张量还是更高维度的数组,ravel() 都会返回一个包含所有元素的、连续的一维数组。

示例:

python 复制代码
import numpy as np

# 二维数组
matrix = np.array([[1, 2, 3],
                   [4, 5, 6]])

# 使用 ravel()
flattened_array = matrix.ravel()

print("原始矩阵:\n", matrix)
print("原始矩阵的 shape:", matrix.shape)
print("\nravel() 之后的结果:", flattened_array)
print("ravel() 之后结果的 shape:", flattened_array.shape)

# 三维数组
tensor = np.arange(12).reshape(2, 3, 2)
print("\n原始张量 shape:", tensor.shape)
print("ravel() 之后结果的 shape:", tensor.ravel().shape)

运行结果:

复制代码
原始矩阵:
 [[1 2 3]
 [4 5 6]]
原始矩阵的 shape: (2, 3)

ravel() 之后的结果: [1 2 3 4 5 6]
ravel() 之后结果的 shape: (6,)

原始张量 shape: (2, 3, 2)
ravel() 之后结果的 shape: (12,)
一个非常重要的特性:视图 (View) vs. 拷贝 (Copy)

ravel() 有一个关键特性:它尽可能地返回原始数组的视图 (view),而不是一个拷贝 (copy)。

  • 视图 (View) :视图只是原始数据的一个"窗口"或"别名"。它不占用新的内存空间。修改视图会直接影响到原始数组。
  • 拷贝 (Copy):拷贝会创建一个全新的数组,占用新的内存空间。修改拷贝不会影响原始数组。

ravel() 只有在数组的内存不连续时才会创建拷贝。在大多数情况下,它返回的是视图,这使得它非常高效

python 复制代码
# ravel() 返回视图的例子
a = np.array([[1, 2], [3, 4]])
b = a.ravel()
b[0] = 99 # 修改视图 b

print("修改 b 之后,原始数组 a 也变了:\n", a)
# 输出:
# [[99  2]
#  [ 3  4]]

替代操作

ravel() 最主要的替代操作是 flatten()reshape()。它们在功能上相似,但有关键的区别。

1. numpy.flatten()

flatten() 的作用和 ravel() 完全一样:将数组压平成一维。

ravel() 的核心区别

flatten() 永远返回一个拷贝 (copy)。

这意味着 flatten() 在内存上开销更大,也更"安全",因为它不会意外地修改原始数据。

python 复制代码
a = np.array([[1, 2], [3, 4]])
c = a.flatten()
c[0] = 99 # 修改拷贝 c

print("修改 c 之后,原始数组 a 保持不变:\n", a)
# 输出:
# [[1 2]
#  [3 4]]
2. numpy.reshape(-1)

你也可以使用 reshape() 来实现压平的效果。将 -1 作为 reshape 的参数,NumPy 会自动计算出总元素数量,并创建一个相应大小的一维数组。

ravel()flatten() 的区别

reshape(-1)ravel() 类似,它也尽可能地返回视图 (view)。

在功能上,reshape(-1)ravel() 几乎是等价的。ravel() 在某些情况下可能稍微快一点,因为它在代码实现上更直接。

python 复制代码
a = np.array([[1, 2], [3, 4]])
d = a.reshape(-1)
d[0] = 99 # 修改视图 d

print("修改 d 之后,原始数组 a 也变了:\n", a)
# 输出:
# [[99  2]
#  [ 3  4]]

总结与如何选择

函数 功能 返回类型 性能 安全性
ravel() 压平成一维 视图 (View) (尽可能) 最高效 较低 (可能意外修改原数据)
flatten() 压平成一维 拷贝 (Copy) (永远) 较低 (有内存开销) 最安全
reshape(-1) 压平成一维 视图 (View) (尽可能) 高效 较低 (可能意外修改原数据)
选择建议:
  • 当你需要绝对保证不修改原始数据时,或者你不确定后续操作是否会修改数组时,请使用 flatten() 这是最安全的选择。
  • 当性能至关重要,且你只是想读取或传递一个一维版本的数组,而不会去修改它时,请使用 ravel()reshape(-1) ravel() 在语义上更清晰地表达了"压平"这个意图。
  • 在机器学习中,ravel() 经常被用在需要将多维特征图或参数展平以输入到全连接层或损失函数的场景中。例如,Scikit-learn 的很多函数在需要一维标签数组时,内部可能会调用 ravel()

总而言之,ravel() 是一个高效的工具,但使用它时需要记住它返回视图的特性。flatten() 是它的安全但稍慢的替代品,而 reshape(-1) 在功能上与 ravel() 非常接近。

相关推荐
No.Ada3 小时前
《基于机器学习的脑电认知负荷识别研究与应用》论文笔记
人工智能·机器学习
咚咚王者4 小时前
人工智能之数据分析 numpy:第四章 数组属性和数据类型
人工智能·数据分析·numpy
LO嘉嘉VE5 小时前
学习笔记十:多分类学习
机器学习
月下倩影时5 小时前
视觉学习篇——理清机器学习:分类、流程与技术家族的关系
学习·机器学习·分类
算法与编程之美5 小时前
探索不同的优化器、损失函数、batch_size对分类精度影响
人工智能·机器学习·计算机视觉·分类·batch
Blossom.11811 小时前
移动端部署噩梦终结者:动态稀疏视觉Transformer的量化实战
java·人工智能·python·深度学习·算法·机器学习·transformer
月下倩影时11 小时前
视觉进阶篇——机器学习训练过程(手写数字识别,量大管饱需要耐心)
人工智能·学习·机器学习
生信大表哥15 小时前
贝叶斯共识聚类(BCC)
机器学习·数据挖掘·聚类
Cathy Bryant19 小时前
信息论(五):联合熵与条件熵
人工智能·笔记·机器学习·数学建模·概率论