numpy中flat和ravel()的区别

22

以下两者有何不同之处?

>>> import numpy as np
>>> arr = np.array([[[  0,   1,   2],
...                  [ 10,  12,  13]],
...                 [[100, 101, 102],
...                  [110, 112, 113]]])
>>> arr
array([[[  0,   1,   2],
        [ 10,  12,  13]],
       [[100, 101, 102],
        [110, 112, 113]]])
>>> arr.ravel()
array([  0,   1,   2,  10,  12,  13, 100, 101, 102, 110, 112, 113])
>>> arr.ravel()[0] = -1
>>> arr
array([[[ -1,   1,   2],
        [ 10,  12,  13]],
       [[100, 101, 102],
        [110, 112, 113]]])
>>> list(arr.flat)
[-1, 1, 2, 10, 12, 13, 100, 101, 102, 110, 112, 113]
>>> arr.flat[0] = 99
>>> arr
array([[[ 99,   1,   2],
        [ 10,  12,  13]],
       [[100, 101, 102],
        [110, 112, 113]]])

除了 flat 返回一个迭代器而不是列表之外,它们似乎是相同的,因为它们都会就地修改原始数组(这与 flatten() 不同,后者返回数组的副本)。那么,flatravel() 之间是否有其他显着的区别?如果没有,什么时候使用其中一个会更有用呢?


np.array(arr.flat) 给出的结果更接近(或者可能相同于)np.ravel(x) - hpaulj
1个回答

20

flat 是一个迭代器。它是一个独立的对象,只能通过索引访问数组元素。它的主要目的是在循环和推导表达式中使用。它提供的顺序与 ravel 得到的顺序相同。

ravel 的结果不同,flat 不是一个 ndarray,除了索引数组和迭代访问数组外,它不能做太多事情。请注意,您必须调用 list 来查看迭代器的内容。例如,arr.flat.min() 会出现 AttributeError 错误,而 arr.ravel().min() 将给出与 arr.min() 相同的结果。

由于 numpy 提供了许多不需要显式循环的操作,ndarray.flat 和一般的迭代器相比很少使用,而更常使用的是 ndarray.ravel()

尽管如此,在某些情况下,迭代器更可取。如果您的数组足够大,并且您正在逐个检查所有元素,则迭代器将很好地工作。特别是当您拥有类似分部加载的内存映射数组时,这一点更为明显。


1
具体来说,flat 会生成一个 np.flatiter 类型的对象(请参阅其文档)。此外,它是作为数组的属性实现的,而不是方法或函数。 - hpaulj
在技术上,“flat”是“ndarray”的一个属性,这意味着它基本上是一个无参数方法,可以作为属性访问,但每次访问时实际上返回一个新实例。@hpaulj - Mad Physicist
1
flat(以及类似shape的属性)在numpyc代码中定义,并且实际上并不使用Python的property机制。它们在功能上看起来相似。 - hpaulj

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接