# [Numpy-discussion] Why ndarray provides four ways to flatten?

Alexander Belopolsky ndarray at mac.com
Tue Oct 28 20:37:59 EDT 2014

```On Tue, Oct 28, 2014 at 1:42 PM, Stephan Hoyer <shoyer at gmail.com> wrote:

> .flat lets you iterate over all elements of a N-dimensional array as if it
> was 1D, without ever needing to make a copy of the array. In contrast,
> ravel() and reshape(-1) cannot always avoid a copy, because they need to
> return another ndarray.

In some cases ravel() returns a copy where a view can be easily constructed.
For example,

>>> x = np.arange(10)
>>> y = x[::2]
>>> y.ravel().flags['OWNDATA']
True

Interestingly, in the same case reshape(-1) returns a view:

>>> y.reshape(-1).flags['OWNDATA']
False

(This suggests at least a documentation bug - numpy.ravel documentation
says that it is equivalent to reshape(-1).)

It is only in situations like this

>>> a = np.arange(16).reshape((4,4))
>>> a[1::2,1::2].ravel()
array([ 5,  7, 13, 15])

where flat view cannot be an ndarray, but .flat can still return something
that is at least duck-typing compatible with ndarray (if not an ndarray
subclass) and behaves as a view into original data.

My preferred design would be for x.flat to return a flat view into x.  This
would be consistent with the way .T and .real attributes are defined and
close enough to .imag.  An obvious way to obtain a flat copy would be
x.flat.copy().  Once we have this, ravel() and flatten() can be deprecated
and reshape(-1) discouraged.

I think this would be backward compatible except for rather questionable
situations like this:

>>> i = x.flat
>>> list(i)
[0, 1, 2, 3, 4, 0, 6, 7, 8, 9]
>>> list(i)
[]
>>> np.array(i)
array([0, 1, 2, 3, 4, 0, 6, 7, 8, 9])
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/numpy-discussion/attachments/20141028/f54259d8/attachment.html>
```