On Fri, Mar 29, 2013 at 10:08 PM, Matthew Brett <matthew.br...@gmail.com> wrote: > > Hi, > > We were teaching today, and found ourselves getting very confused > about ravel and shape in numpy. > > Summary > -------------- > > There are two separate ideas needed to understand ordering in ravel and > reshape: > > Idea 1): ravel / reshape can proceed from the last axis to the first, > or the first to the last. This is "ravel index ordering" > Idea 2) The physical layout of the array (on disk or in memory) can be > "C" or "F" contiguous or neither. > This is "memory ordering" > > The index ordering is usually (but see below) orthogonal to the memory > ordering. > > The 'ravel' and 'reshape' commands use "C" and "F" in the sense of > index ordering, and this mixes the two ideas and is confusing. > > What the current situation looks like > ---------------------------------------------------- > > Specifically, we've been rolling this around 4 experienced numpy users > and we all predicted at least one of the results below wrongly. > > This was what we knew, or should have known: > > In [2]: import numpy as np > > In [3]: arr = np.arange(10).reshape((2, 5)) > > In [5]: arr.ravel() > Out[5]: array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9]) > > So, the 'ravel' operation unravels over the last axis (1) first, > followed by axis 0. > > So far so good (even if the opposite to MATLAB, Octave). > > Then we found the 'order' flag to ravel: > > In [10]: arr.flags > Out[10]: > C_CONTIGUOUS : True > F_CONTIGUOUS : False > OWNDATA : False > WRITEABLE : True > ALIGNED : True > UPDATEIFCOPY : False > > In [11]: arr.ravel('C') > Out[11]: array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9]) > > But we soon got confused. How about this? > > In [12]: arr_F = np.array(arr, order='F') > > In [13]: arr_F.flags > Out[13]: > C_CONTIGUOUS : False > F_CONTIGUOUS : True > OWNDATA : True > WRITEABLE : True > ALIGNED : True > UPDATEIFCOPY : False > > In [16]: arr_F > Out[16]: > array([[0, 1, 2, 3, 4], > [5, 6, 7, 8, 9]]) > > In [17]: arr_F.ravel('C') > Out[17]: array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9]) > > Right - so the flag 'C' to ravel, has got nothing to do with *memory* > ordering, but is to do with *index* ordering. > > And in fact, we can ask for memory ordering specifically: > > In [22]: arr.ravel('K') > Out[22]: array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9]) > > In [23]: arr_F.ravel('K') > Out[23]: array([0, 5, 1, 6, 2, 7, 3, 8, 4, 9]) > > In [24]: arr.ravel('A') > Out[24]: array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9]) > > In [25]: arr_F.ravel('A') > Out[25]: array([0, 5, 1, 6, 2, 7, 3, 8, 4, 9]) > > There are some confusions to get into with the 'order' flag to reshape > as well, of the same type. > > Ravel and reshape use the tems 'C' and 'F" in the sense of index ordering. > > This is very confusing. We think the index ordering and memory > ordering ideas need to be separated, and specifically, we should avoid > using "C" and "F" to refer to index ordering. > > Proposal > ------------- > > * Deprecate the use of "C" and "F" meaning backwards and forwards > index ordering for ravel, reshape > * Prefer "Z" and "N", being graphical representations of unraveling in > 2 dimensions, axis1 first and axis0 first respectively (excellent > naming idea by Paul Ivanov) > > What do y'all think? > > Cheers, > > Matthew > Paul Ivanov > JB Poline > _______________________________________________ > NumPy-Discussion mailing list > NumPy-Discussion@scipy.org > http://mail.scipy.org/mailman/listinfo/numpy-discussion
I always thought "F" and "C" are easy to understand, I always thought about the content and never about the memory when using it. In my numpy htmlhelp for version 1.5, I don't have a K or A option >>> np.__version__ '1.5.1' >>> np.arange(5).ravel("K") Traceback (most recent call last): File "<stdin>", line 1, in <module> TypeError: order not understood >>> np.arange(5).ravel("A") array([0, 1, 2, 3, 4]) >>> the C, F in ravel have their twins in reshape >>> arr = np.arange(10).reshape(2,5, order="C").copy() >>> arr array([[0, 1, 2, 3, 4], [5, 6, 7, 8, 9]]) >>> arr.ravel() array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9]) >>> arr = np.arange(10).reshape(2,5, order="F").copy() >>> arr array([[0, 2, 4, 6, 8], [1, 3, 5, 7, 9]]) >>> arrarr.ravel("F") array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9]) For example we use it when we get raveled arrays from R, and F for column order and C for row order indexing are pretty obvious names when coming from another package (Matlab, R, Gauss) Josef _______________________________________________ NumPy-Discussion mailing list NumPy-Discussion@scipy.org http://mail.scipy.org/mailman/listinfo/numpy-discussion