@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 C-contiguous. 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/scikit-image/scikit-image/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 "scikit-image" group. To unsubscribe from this group and stop receiving emails from it, send an email to scikit-image+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 "scikit-image" group. To unsubscribe from this group and stop receiving emails from it, send an email to scikit-image+unsubscribe@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out.
participants (1)
-
Juan Nunez-Iglesias