@Marc: They are very different functions. ravel() gives you a view or a copy of the array as a 1D array that happens to be contiguous. ascontiguousarray will give you a view or a copy of the array *of the same shape* as the original, but guaranteed to be contiguous. Let me try to illustrate: In [1]: x = np.arange(20, dtype=np.uint8).reshape((4,5)) In [2]: x Out[2]: array([[ 0, 1, 2, 3, 4], [ 5, 6, 7, 8, 9], [10, 11, 12, 13, 14], [15, 16, 17, 18, 19]], dtype=uint8) In [3]: x.strides Out[3]: (5, 1) So I've made an array x that has 4 rows and 5 columns. Internally, the data in x is stored as a contiguous block of memory of length 20 bytes. The strides tell numpy that to get to the next row in the array, you need to skip 5 bytes in the memory, but to get to the next column, you only need to go to the next (+1) byte in memory. This is called Ccontiguous. Now, let's get a weird view of x: In [4]: y = x.T[1::2] I've taken the transpose of x (5 rows and 4 columns) and then taken the 1st and 3rd rows of that. By default, numpy will use nice tricks with strides to avoid a copy: In [5]: y.strides Out[5]: (2, 5) In [6]: y Out[6]: array([[ 1, 6, 11, 16], [ 3, 8, 13, 18]], dtype=uint8) In [7]: y[1, 1] = 45 In [8]: x Out[8]: array([[ 0, 1, 2, 3, 4], [ 5, 6, 7, 45, 9], [10, 11, 12, 13, 14], [15, 16, 17, 18, 19]], dtype=uint8) So, y is actually pointing to the same memory as x, but it uses different strides to access its own rows and columns. Notice that changing an entry in y changed the corresponding entry in x. In [10]: np.ravel(y) Out[10]: array([ 1, 6, 11, 16, 3, 45, 13, 18], dtype=uint8) np.ravel gives you a "linearised" version of y, concatenating all the rows together. In [11]: z = np.ascontiguousarray(y) In [12]: z Out[12]: array([[ 1, 6, 11, 16], [ 3, 45, 13, 18]], dtype=uint8) In [13]: z.strides Out[13]: (4, 1) np.ascontiguousarray gives you the same thing as y, except now it's a separate contiguous block of memory: look at the strides. You can tell that it's a copy because modifying z has no effect on x: In [14]: z[0, 0] = 72 In [15]: x Out[15]: array([[ 0, 1, 2, 3, 4], [ 5, 6, 7, 45, 9], [10, 11, 12, 13, 14], [15, 16, 17, 18, 19]], dtype=uint8) In [16]: z Out[16]: array([[72, 6, 11, 16], [ 3, 45, 13, 18]], dtype=uint8) But, if an array is already contiguous, np.ravel() avoids a copy and returns a view into the same data. So: In [19]: a = np.ravel(x) In [20]: a[0] = 72 In [21]: x Out[21]: array([[72, 1, 2, 3, 4], [ 5, 6, 7, 45, 9], [10, 11, 12, 13, 14], [15, 16, 17, 18, 19]], dtype=uint8) If you try to get a contiguous version of x, which is already contiguous, you are actually getting x back: In [22]: b = np.ascontiguousarray(x) In [23]: b is x Out[23]: True In [25]: b[3, 4] = 0 In [26]: x Out[26]: array([[72, 1, 2, 3, 4], [ 5, 6, 7, 45, 9], [10, 11, 12, 13, 14], [15, 16, 17, 18, 0]], dtype=uint8) Hope that clarifies a few things! It takes quite a bit of playing around before you can get an intuition for what's a copy, what's a view, what's contiguous, etc. On Wed, Jul 31, 2013 at 6:15 PM, Ankit Agrawal <aaaagrawal@gmail.com> wrote:
Hi Marc,
On Wed, Jul 31, 2013 at 1:09 PM, Marc de Klerk <deklerkmc@gmail.com>wrote:
Hi guys,
I've been using np.ravel(). This morning I tried to lookup the difference between np.ravel() and np.ascontiguousarray(). Does anybody know?
I am not sure if this helps as I don't know your purpose for using np.ravel / np.ascontiguousarray. I got to know about the ndarray.flags method yesterday from Stefan while discussion on this PR<https://github.com/scikitimage/scikitimage/pull/668> .
In [15]: a = np.arange(20).reshape((4,5))
In [16]: a Out[16]: array([[ 0, 1, 2, 3, 4], [ 5, 6, 7, 8, 9], [10, 11, 12, 13, 14], [15, 16, 17, 18, 19]])
In [17]: a.flags Out[17]: C_CONTIGUOUS : True F_CONTIGUOUS : False OWNDATA : False WRITEABLE : True ALIGNED : True UPDATEIFCOPY : False
In [18]: b = np.ravel(a)
In [20]: b Out[20]: array([ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19])
In [21]: b.flags Out[21]: C_CONTIGUOUS : True F_CONTIGUOUS : True OWNDATA : False WRITEABLE : True ALIGNED : True UPDATEIFCOPY : False
Hope this helps!!
Marc
On Sunday, July 21, 2013 6:37:47 AM UTC+2, Chintak Sheth wrote:
Hi Ronnie,
On Jul 21, 2013 10:00 AM, "Ronnie Ghose" <ronnie...@gmail.com> wrote:
So in skimage/colors why does it matter if the array is contiguous? Is
this for Cython operations later?
Yeah it is mainly for using memory views in Cython which is initialized as C contiguous. `cdef some_type[:. ::1] var_name`
In thus case ::1 is for C contiguous.
Chintak
 You received this message because you are subscribed to the Google Groups "scikitimage" group. To unsubscribe from this group and stop receiving emails from it, send an email to scikitimage+unsubscribe@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out.
 You received this message because you are subscribed to the Google Groups "scikitimage" group. To unsubscribe from this group and stop receiving emails from it, send an email to scikitimage+unsubscribe@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out.
participants (1)

Juan NunezIglesias