User guide
NumPy User Guide, Release 1.9.0
NPY_ARRAY_ENSUREARRAY
Make sure the resulting object is an actual ndarray and not a sub- class.
Note: Whether or not an array is byte-swapped is determined by the data-type of the array. Native byte-order arrays
are always requested by PyArray_FROM_OTF and so there is no need for a NPY_ARRAY_NOTSWAPPED flag in the
requirements argument. There is also no way to get a byte-swapped array from this routine.
Creating a brand-new ndarray
Quite often new arrays must be created from within extension-module code. Perhaps an output array is needed and you
don’t want the caller to have to supply it. Perhaps only a temporary array is needed to hold an intermediate calculation.
Whatever the need there are simple ways to get an ndarray object of whatever data-type is needed. The most general
function for doing this is PyArray_NewFromDescr. All array creation functions go through this heavily re-used
code. Because of its flexibility, it can be somewhat confusing to use. As a result, simpler forms exist that are easier to
use.
PyObject *PyArray_SimpleNew(int nd, npy_intp* dims, int typenum)
This function allocates new memory and places it in an ndarray with nd dimensions whose shape is determined
by the array of at least nd items pointed to by dims. The memory for the array is uninitialized (unless typenum
is NPY_OBJECT in which case each element in the array is set to NULL). The typenum argument allows
specification of any of the builtin data-types such as NPY_FLOAT or NPY_LONG. The memory for the array
can be set to zero if desired using PyArray_FILLWBYTE (return_object, 0).
PyObject *PyArray_SimpleNewFromData(int nd, npy_intp* dims, int typenum, void* data)
Sometimes, you want to wrap memory allocated elsewhere into an ndarray object for downstream use. This rou-
tine makes it straightforward to do that. The first three arguments are the same as in PyArray_SimpleNew,
the final argument is a pointer to a block of contiguous memory that the ndarray should use as it’s data-buffer
which will be interpreted in C-style contiguous fashion. A new reference to an ndarray is returned, but the
ndarray will not own its data. When this ndarray is deallocated, the pointer will not be freed.
You should ensure that the provided memory is not freed while the returned array is in existence. The easiest
way to handle this is if data comes from another reference-counted Python object. The reference count on this
object should be increased after the pointer is passed in, and the base member of the returned ndarray should
point to the Python object that owns the data. Then, when the ndarray is deallocated, the base-member will be
DECREF’d appropriately. If you want the memory to be freed as soon as the ndarray is deallocated then simply
set the OWNDATA flag on the returned ndarray.
Getting at ndarray memory and accessing elements of the ndarray
If obj is an ndarray (PyArrayObject
*
), then the data-area of the ndarray is pointed to by the void* pointer
PyArray_DATA (obj) or the char* pointer PyArray_BYTES (obj). Remember that (in general) this data-area may
not be aligned according to the data-type, it may represent byte-swapped data, and/or it may not be writeable. If the
data area is aligned and in native byte-order, then how to get at a specific element of the array is determined only by
the array of npy_intp variables, PyArray_STRIDES (obj). In particular, this c-array of integers shows how many
bytes must be added to the current element pointer to get to the next element in each dimension. For arrays less
than 4-dimensions there are PyArray_GETPTR{k} (obj, ...) macros where {k} is the integer 1, 2, 3, or 4 that
make using the array strides easier. The arguments .... represent {k} non- negative integer indices into the array.
For example, suppose E is a 3-dimensional ndarray. A (void*) pointer to the element E[i,j,k] is obtained as
PyArray_GETPTR3 (E, i, j, k).
As explained previously, C-style contiguous arrays and Fortran-style contiguous arrays have particular striding pat-
terns. Two array flags (NPY_C_CONTIGUOUS and :cdata‘NPY_F_CONTIGUOUS‘) indicate whether or not the
striding pattern of a particular array matches the C-style contiguous or Fortran-style contiguous or neither. Whether or
5.1. How to extend NumPy 59