numpy 中的 flatten 和 ravel 函数有什么区别?

What is the difference between flatten and ravel functions in numpy?

import numpy as np
y = np.array(((1,2,3),(4,5,6),(7,8,9)))
OUTPUT:
print(y.flatten())
[1   2   3   4   5   6   7   8   9]
print(y.ravel())
[1   2   3   4   5   6   7   8   9]

两个函数 return 相同的列表。 那么执行相同工作的两个不同功能需要什么。

目前的API是:

  • flatten总是returns一份。
  • ravel returns 尽可能查看原始数组。这在打印输出中不可见,但如果您修改 ravel 返回的数组,它可能会修改原始数组中的条目。如果您修改从展平返回的数组中的条目,这将永远不会发生。 ravel 通常会更快,因为没有内存被复制,但是你必须更加小心地修改它的数组 returns.
  • reshape((-1,)) 只要数组的步幅允许,就会获取视图,即使这意味着您并不总是获得连续的数组。

正如所解释的那样一个关键的区别是:

  • flatten 是 ndarray 对象的一种方法,因此只能为真正的 numpy 数组调用。

  • ravel 是库级函数,因此可以在任何可以成功解析的对象上调用。

例如,ravel 将适用于 ndarray 列表,而 flatten 不适用于该类型的对象。

@IanH 在他的回答中也指出了内存处理的重要区别。

以下是函数的正确命名空间:

这两个函数 return 扁平化一维数组指向新的内存结构。

import numpy
a = numpy.array([[1,2],[3,4]])

r = numpy.ravel(a)
f = numpy.ndarray.flatten(a)  

print(id(a))
print(id(r))
print(id(f))

print(r)
print(f)

print("\nbase r:", r.base)
print("\nbase f:", f.base)

---returns---
140541099429760
140541099471056
140541099473216

[1 2 3 4]
[1 2 3 4]

base r: [[1 2]
 [3 4]]

base f: None

在上面的例子中:

  • 结果的内存位置不同,
  • 结果看起来一样
  • 扁平化会 return 一个副本
  • ravel 会 return 一个视图。

我们如何检查某物是否是副本? 使用 ndarray.base 属性。如果是视图,则基数将是原始数组;如果是副本,则基数将为 None.


检查 a2 是否是 a1

的副本
import numpy
a1 = numpy.array([[1,2],[3,4]])
a2 = a1.copy()
id(a2.base), id(a1.base)

输出:

(140735713795296, 140735713795296)