Вопрос

follow up question to how to pass numpy array to Cython function correctly?:

when passing numpy.ndarrays in Cython to a C function that only deals with contiguous arrays, is there a difference between doing:

np.ndarray[double, ndim=1, mode="c"] arr = np.ascontiguousarray(np.array([1,2,3],dtype=float))

and

np.ndarray[double, ndim=1, mode="c"] arr = np.asarray(np.array([1,2,3],dtype=float), order="c")

are both necessary? Does np.ascontiguous implies already that the array will be in a format that can be assigned to an array with a mode=c declaration?

Это было полезно?

Решение 2

You should be able to just do:

np.ndarray[double, ndim=1, mode="c"] arr = np.array([1,2,3], dtype=np.float64, order="c")

From the docs for np.array:

order : {'C', 'F', 'A'}, optional
    Specify the order of the array.  If order is 'C' (default), then the
    array will be in C-contiguous order (last-index varies the
    fastest).  If order is 'F', then the returned array
    will be in Fortran-contiguous order (first-index varies the
    fastest).  If order is 'A', then the returned array may
    be in any order (either C-, Fortran-contiguous, or even
    discontiguous).

My understanding is that you only need to use np.ascontiguousarray if the array you are trying to pass was generated from some non-contiguous slice of another array. If you are creating the array from scratch, it shouldn't be necessary.

For example:

a = np.arange(10)
a.flags['C_CONTIGUOUS'] # True
b = a[::2]
b.flags['C_CONTIGUOUS'] # False

c = np.ascontiguousarray(b)
c.flags['C_CONTIGUOUS'] # True

Also, perhaps consider using the typed memoryview interface

double[::1] arr = np.array([1,2,3], dtype=np.float64)

Другие советы

The docs for ascontiguousarray states that it will return a C ordered array, so yes, if you use ascontiguousarray you can then assume the data is ordered in c mode.

To then answer what differences are there between the two, we can read the source.

asarray (link) does this:

return array(a, dtype, copy=False, order=order)

ascontiguousarray (link) does this:

return array(a, dtype, copy=False, order='C', ndmin=1)

so when you call asarray with order='C', the only difference with ascontiguousarray is that you choose the default value for ndmin, which is 0. This boils down to this difference, when you use the two methods on a single number instead of a list:

print asarray(4,dtype='float',order='c').shape
()
print ascontiguousarray(4,dtype='float').shape
(1,)

It's up to you, but I prefer ascontiguousarray, as I often rely on the possibility of processing the shape attribute of the array, and expect it to be non-empty. In a sense, it's like calling atleast1d as well at the same time.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top