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]

两个函数返回相同的列表。 那么,两个不同的职能部门执行同一项工作的需求是什么呢?


当前回答

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

Flatten是ndarray对象的一个方法,因此只能用于真正的numpy数组。 Ravel是一个库级函数,因此可以在任何可以成功解析的对象上调用。

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

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

其他回答

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

Flatten是ndarray对象的一个方法,因此只能用于真正的numpy数组。 Ravel是一个库级函数,因此可以在任何可以成功解析的对象上调用。

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

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

当前的API是:

flatten always returns a copy. ravel returns a view of the original array whenever possible. This isn't visible in the printed output, but if you modify the array returned by ravel, it may modify the entries in the original array. If you modify the entries in an array returned from flatten this will never happen. ravel will often be faster since no memory is copied, but you have to be more careful about modifying the array it returns. reshape((-1,)) gets a view whenever the strides of the array allow it even if that means you don't always get a contiguous array.

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

numpy.ndarray.flatten numpy.ravel

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

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

在上面的例子中:

结果的记忆位置是不同的, 结果看起来是一样的 Flatten将返回一个副本 拉威尔将返回一个视图。

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


检查a2是否是a1的副本

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

Out:

(140735713795296, 140735713795296)