机器学习之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() 非常接近。

相关推荐
纪伊路上盛名在7 分钟前
机器学习中的固定随机种子方案
人工智能·机器学习·数据分析·随机种子
Sagittarius_A*38 分钟前
监督学习(Supervised Learning)
人工智能·学习·机器学习·监督学习
智算菩萨2 小时前
【论文精读】Automated machine learning for positive-unlabelled learning
论文阅读·人工智能·机器学习·论文笔记·贝叶斯优化·自动机器学习·无标签学习
codeの诱惑4 小时前
推荐算法(一):数学基础回顾——勾股定理与欧氏距离
算法·机器学习·推荐算法
codeの诱惑4 小时前
推荐算法(三):余弦定理和余弦相似度的关系及公式推导
人工智能·机器学习·推荐算法
larance5 小时前
[菜鸟教程] 机器学习教程第一课
人工智能·机器学习
bryant_meng6 小时前
【AI】《Explainable Machine Learning》(2)
人工智能·深度学习·机器学习·计算机视觉·explanation
老鱼说AI6 小时前
大模型学习与面试精讲第六期:损失函数篇
人工智能·深度学习·神经网络·学习·机器学习·语言模型
娃娃略7 小时前
【CFG】——条件生成
人工智能·机器学习
哥布林学者7 小时前
深度学习进阶(一)从注意力到自注意力
机器学习·ai