# [Numpy-discussion] Raveling, reshape order keyword unnecessarily confuses index and memory ordering

josef.pktd at gmail.com josef.pktd at gmail.com
Thu Apr 4 23:38:52 EDT 2013

Catching up with numpy 1.6

> 'No' means: I don't think it makes sense given the current behavior of numpy
> with respect to functions that are designed to return views
> (and copy memory only if there is no way to make a view)
>
> One objective of functions that create views is *not* to change the underlying
> memory. So in most cases, requesting a specific contiguity (memory order)
> for a new array, when you actually want a view with strides, doesn't
> sound like an obvious explanation for "order".
>

why I'm buffled:

To me views are just  a specific way of looking at an existing array, or
parts of it, similar to an iteratior but with an n-dimensional shape.

ravel is just like calling list(iterator), the iterator determines how we read
the existing array.

the output of an iterator?

I (and statsmodels) are still on numpy 1.5 but not for much longer.
So I'm trying to read up

http://docs.scipy.org/doc/numpy/reference/arrays.nditer.html#single-array-iteration
explains the case for "K" :

for elementwise operations just run the fastest way through the array

The old flat and flatiter where always c-order.

>>> a = np.arange(4*5).reshape(4,5)
>>> b = np.array(a, order='F')
>>> np.fromiter(np.nditer(b, order='K'), int)
array([ 0,  5, 10, 15,  1,  6, 11, 16,  2,  7, 12, 17,  3,  8, 13, 18,  4,
9, 14, 19])
>>> np.fromiter(np.nditer(a, order='K'), int)
array([ 0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 15, 16,
17, 18, 19])

Is ravel('K') good for anything ?

>>> def f(x):
'''A function that only works in 1d'''
if x.ndim > 1: raise ValueError
return np.round(np.piecewise(x, [x < 0, x >= 0], [lambda x:
np.sqrt(-x), lambda x: np.sqrt(x)]))

>>> b = np.array(np.arange(4*5.).reshape(4,5), order='F')
>>> b
array([[  0.,   1.,   2.,   3.,   4.],
[  5.,   6.,   7.,   8.,   9.],
[ 10.,  11.,  12.,  13.,  14.],
[ 15.,  16.,  17.,  18.,  19.]])

>>> f(b[:,:2])
Traceback (most recent call last):
File "<pyshell#184>", line 1, in <module>
f(b[:,:2])
File "<pyshell#183>", line 2, in f
if x.ndim > 1: raise ValueError
ValueError

ravel and reshape with 'K' doesn't roundtrip

>>> (b.ravel('K')).reshape(b.shape, order='K')
array([[  0.,   5.,  10.,  15.,   1.],
[  6.,  11.,  16.,   2.,   7.],
[ 12.,  17.,   3.,   8.,  13.],
[ 18.,   4.,   9.,  14.,  19.]])

but we can do inplace transformations with it

>>> e = b[:,:2].ravel()
>>> e.flags.owndata
True
>>> e = b[:,:2].ravel('K')
>>> e.flags.owndata
False

>>> e[:] = f(e)
>>> b
array([[  0.,   1.,   2.,   3.,   4.],
[  2.,   2.,   7.,   8.,   9.],
[  3.,   3.,  12.,  13.,  14.],
[  4.,   4.,  17.,  18.,  19.]])
>>> e[:] = f(e)
>>> b
array([[  0.,   1.,   2.,   3.,   4.],
[  1.,   1.,   7.,   8.,   9.],
[  2.,   2.,  12.,  13.,  14.],
[  2.,   2.,  17.,  18.,  19.]])

(A few hours of experimenting is more that I wanted to know,
99.5% of my cases are order='C' or order='F')

nditer has also an interesting section on Iterator-Allocated Output Arrays

Josef
I found the scissors