I want to use an array buffer object that can be used in both Python and C on Cython. It seems that there are Cython's cython.view.array
and CPython's ʻarray.array`.
Cython array
Use cython.view.array
.
cython
from cython.view cimport array # note that this is 'c'-import
arr = array(shape=(3,3,3), itemsize=sizeof(int), format='i')
For Python floats you would use double with'd'. As an arrangement in memory, you can use the keyword "mode" in cython, like order in numpy.
By assigning directly to an array of the corresponding data type, it can be treated as a C array (or pointer) (actually, the "view" for array will be in the C array).
cython
from cython.view cimport array
arr = array(shape=(3, 10), itemsize=sizeof(double), format='d')
cdef double[:,:] carr2d = arr # 2D C-array view
cdef double[:] carr1d = arr # 1D C-array view
It can be triggered not only by explicit assignment as above, but also by specifying function arguments.
cython
cpdef double process(double[:,:] view) nogil:
...
arr = array(shape=(3, 10), itemsize=sizeof(double), format='d')
process(arr)
Python array
You need import array
in the Python statement and `` `from cpython cimport array``` as the Cython type information.
In Benchmark on StackOverflow, "From cython array It's also fast, "but I don't know how it really is.
Also, it seems that it can handle only basic 1D arrays, so it may be troublesome if you want to access 2D in Cython.
For now, the only way to make it work like ``` numpy.empty ()`` is to use ``
clone ()` ``.
cython
from cpython cimport array as carray
import array
cdef carray.array template = array.array('d')
cdef carray.array buffer = carray.clone(template, 1000, zero=False)
#This clone()The function is defined on the cython side
# 'zero'Specify whether to initialize to zero with a keyword
data
To membersas_xxxs
Or```as_voidptr``Field is defined, this is an array/Acts as a pointer.
cython
from libc.stdio cimport printf
printf ("% c", buffer.data.as_chars [0]) # Print the first element
Accessing this pointer is dangerous because there is no type check, but it is fast because it is not bound by the GIL.
Ichiou memoryview method can be assigned (but GIL is required). In this case, it is unclear whether a two-dimensional or higher view can be created.
#Easy to use conversion on Python
##Conversion to Python string
byte type one-dimensional array(View)In the case of, it can be converted to a Python string.
cython
pystring = bytearr.tobytes().decode('utf8')
# Specify the appropriate encoding
##Conversion to NumPy ndarray
cython.view.array is also array.array can also be used as a buffer object, so numpy.asarray()And numpy.array()It seems that it can be converted with.
#Summary
Functionally, it's not that different.
+If you want speed even if it becomes one-dimensional```array.array```Would be better.
+If you want to use it as a multidimensional array in Cython```cython.view.array```Would be better.
Recommended Posts