[PYTHON] Array buffer object for use with Cython

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.

Initialization

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.

Extract as C array (Memory view)

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.

Initialization

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

Extract as C array

dataTo membersas_xxxsOr```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

Array buffer object for use with Cython
Wrap C with Cython for use from Python
Wrap C ++ with Cython for use from Python
Use Cython with Jupyter Notebook
TypeError: Cannot change data-type for object array.
Use DeepL with python (for dissertation translation)
Add the attribute of the object of the class with the for statement
Install tweepy with pip and use it for API 1.1
Use mecab-ipadic-neologd with igo-python
Use RTX 3090 with PyTorch
Use ansible with cygwin
Use pipdeptree with virtualenv
[Python] Use JSON with Python
Use Mock with pytest
Use indicator with pd.merge
Row profiling with Cython
Use Gentelella with django
Use mecab with Python3
Use tensorboard with Chainer
Use DynamoDB with Python
Use pip with MSYS2
Python-accelerate programs with Cython
Use Python 3.8 with Anaconda
Use pyright with Spacemacs
Use TypeScript with django-compressor
Use MySQL with Django
Use Enums with SQLAlchemy
Use tensorboard with NNabla
Use GPS with Edison
Use nim with Jupyter
[python] A note when trying to use numpy with Cython
Turn an array of strings with a for statement (Python3)