在 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]

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

当前的 API 是:

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

正如这里所解释的,一个关键的区别是:

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

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

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

@IanH在他的回答中还指出了内存处理的重要差异。

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

  • numpy.ndarray.flatten

  • numpy.ravel

这两个函数都返回指向新内存结构的扁平一维数组。

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

在上面的示例中:

  • 结果的内存位置不同,
  • 结果看起来是一样的
  • 展平将返回副本
  • 拉维尔会返回一个视图。

我们如何检查某些东西是否是副本?使用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)

最新更新