[Pyrex] experiences with numpy array import/export in pyrex
Filip Wasilewski
filip at ftv.pl
Wed May 3 21:28:27 CEST 2006
Hi,
> I was curious if there are people who have tried numpy/pyrex in such a way
> that they could dynamically export arrays into python.
> What I had in mind was a pyrex function which takes a number of numpy arrays
> as input (images of a video sequence). Then manipulate the array data (fast)
> by use of a pointer to the raw array data. And output a number of newly
> allocated arrays (filled and allocated in C of course, but returning python
> numpy objects).
Maybe not video sequences but exactly like this.
> This means creating new numpy arrays and associated buffers by use of malloc
> and then exporting these into numpy python arrays.. quite difficult...
Hopefully there are simpler ways to access numpy arrays data and expose
your own data.
1. Use Python buffer interface http://docs.python.org/api/abstract-buffer.html,
but I don't think you are looking for this so go to point 2.
2. Declare ndarray external extension type and take the advantage of
Pyrex language. This is the simplest and most common way of directly
using (reading/writing) numpy arrays (not only given as input, but
also created in your code). See a standard example:
# compile as normal Pyrex module
# assuming a recent numpy (>=0.9.6)
cdef extern from "numpy/arrayobject.h":
ctypedef int intp
ctypedef extern class numpy.dtype [object PyArray_Descr]:
cdef int type_num, elsize, alignment
cdef char type, kind, byteorder, hasobject
cdef object fields, typeobj
ctypedef extern class numpy.ndarray [object PyArrayObject]:
cdef char *data
cdef int nd
cdef intp *dimensions
cdef intp *strides
cdef object base
cdef dtype descr
cdef int flags
void import_array()
import numpy
import_array()
def fun(ndarray input_array):
## do some basic checking
if input_array.descr.type != C"d":
raise TypeError("Double array required")
if input_array.nd <> 2:
raise ValueError("2 dimensional array required")
## also check input_array.flags here
cdef int x, y
cdef double *input_data, *output_data
cdef ndarray output_array
x = input_array.dimensions[0]
y = input_array.dimensions[1]
input_data = <double*> input_array.data
## create some output array
## this can be done in Python or with numpy C-api (seek for PyArray_SimpleNew)
output_array = numpy.zeros((10,10), 'd')
output_data = <double*> output_array.data
## do the stuff
return output_array
## end
Here, the numpy array is created with standard numpy function. There are
also special functions in the C-api to create array object.
The thing you probably shouldn't do is to mix array objects and custom
mallocated data. I don't.
3. Use array interface (my favourite) to directly access numpy/Numeric/...
data and/or return data wrapped in Python extensions.
This approach is very flexible because yours and others code can work
with data of any object that exposes this interface.
There are some nice examples of this in the scipy cookbook "Using
NumPy With Other Languages" section at http://scipy.org/Wiki/Cookbook/,
especially
http://scipy.org/Wiki/Cookbook/A_Numerical_Agnostic_Pyrex_Class and
http://scipy.org/Wiki/Cookbook/ArrayStruct_and_Pyrex.
For specification see http://numeric.scipy.org/array_interface.html.
To sum up, if you are looking for a way to expose a custom mallocated
data then use array interface to wrap it. If you only want to allocate
numpy array and modify it's content then use numpy functions to create
arrays and one of the given methods (2. or 3.) to access them.
Filip
More information about the Pyrex
mailing list