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

josef.pktd@gmai... josef.pktd@gmai...
Thu Apr 4 22:38:52 CDT 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.

So, asking about the output memory order made no sense to me. What's
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


More information about the NumPy-Discussion mailing list