2016-07-13 39 views
8

以下几点有什么区别?flat和ravel之间的numpy差异()

>>> 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()之间是否还有其他重要的区别?如果不是,那么使用一个而不是另一个会有什么用处?

+0

'np.array(arr.flat)'给出了更接近np.ravel(x)'的东西(可能是相同的)。 – hpaulj

回答

8

flat是一个迭代器。它是一个单独的对象,恰好通过索引来访问数组元素。它的主要目的是用于循环和理解表达式。它给出的顺序与您通常从ravel获得的顺序相同。

ravel的结果不同,flat不是ndarray,所以除了索引数组和迭代它之外,它不能做很多事情。注意你必须调用list来查看迭代器的内容。例如,arr.flat.min()将以AttributeError失败,而arr.ravel().min()会得出与arr.min()相同的结果。

由于numpy提供了很多不需要显式循环写入的操作,因此和迭代器通常很少使用,与ndarray.ravel()相比很少使用。

这就是说,有些情况下迭代器是可取的。如果你的数组足够大,并且你试图逐个检查所有的元素,那么迭代器就能正常工作。如果你有像内存映射数组那样被加载的东西,这是尤其如此。

+1

具体而言'flat'产生一个'np.flatiter'类型的对象(参见文档)。它也作为数组的属性实现,而不是方法或函数。 – hpaulj

+0

@hpaulj技术上'flat'是'ndarray'的一个属性,这意味着它基本上是一个作为属性访问的无参数方法,但每次访问时都会返回一个新实例。 –

+1

'flat'(沿着类似'shape'的属性)在'numpy''''代码中定义,并且实际上并没有使用Python的'property'机制:'numpy/core/src/multiarray/getset.c' 。在功能上它们看起来相似。 – hpaulj