Exemplo n.º 1
0
/*NUMPY_API
 *
 * Returns false if the array has no NA support. Returns
 * true if the array has NA support AND there is an
 * NA anywhere in the array.
 *
 * If 'wheremask' is non-NULL, only positions with True
 * in 'wheremask' are checked for NA.
 *
 * The parameter 'whichna' is not yet supported, but is
 * provided for future multi-NA support. It should be set
 * to NULL.
 *
 * Returns -1 on failure, otherwise 0 for False and 1 for True.
 */
NPY_NO_EXPORT int
PyArray_ContainsNA(PyArrayObject *arr, PyArrayObject *wheremask,
                   npy_bool *whichna)
{
    /* Validate that the parameter for future expansion is NULL */
    if (whichna != NULL) {
        PyErr_SetString(PyExc_RuntimeError,
                        "multi-NA is not yet supported in PyArray_ContainsNA");
        return -1;
    }

    if (wheremask == NULL) {
        /* Need NA support to contain NA */
        if (PyArray_HASMASKNA(arr)) {
            int idim, ndim;
            char *data;
            npy_intp shape[NPY_MAXDIMS], strides[NPY_MAXDIMS];
            npy_intp i, coord[NPY_MAXDIMS];

            if (PyArray_HASFIELDS(arr)) {
                PyErr_SetString(PyExc_RuntimeError,
                                "field-NA is not yet supported");
                return -1;
            }

            /* Use raw iteration with no heap memory allocation */
            if (PyArray_PrepareOneRawArrayIter(
                        PyArray_NDIM(arr), PyArray_DIMS(arr),
                        PyArray_MASKNA_DATA(arr), PyArray_MASKNA_STRIDES(arr),
                        &ndim, shape,
                        &data, strides) < 0) {
                return -1;
            }

            /* Do the iteration */
            NPY_RAW_ITER_START(idim, ndim, coord, shape) {
                char *d = data;
                /* Process the innermost dimension */
                for (i = 0; i < shape[0]; ++i, d += strides[0]) {
                    if (!NpyMaskValue_IsExposed((npy_mask)(*d))) {
                        return 1;
                    }
                }
            }
            NPY_RAW_ITER_ONE_NEXT(idim, ndim, coord, shape, data, strides);
        }
    }
Exemplo n.º 2
0
static PyObject *
array_slice(PyArrayObject *self, Py_ssize_t ilow, Py_ssize_t ihigh)
{
    PyArrayObject *ret;
    PyArray_Descr *dtype;
    Py_ssize_t dim0;
    char *data;
    npy_intp shape[NPY_MAXDIMS];

    if (PyArray_NDIM(self) == 0) {
        PyErr_SetString(PyExc_ValueError, "cannot slice a 0-d array");
        return NULL;
    }

    dim0 = PyArray_DIM(self, 0);
    if (ilow < 0) {
        ilow = 0;
    }
    else if (ilow > dim0) {
        ilow = dim0;
    }
    if (ihigh < ilow) {
        ihigh = ilow;
    }
    else if (ihigh > dim0) {
        ihigh = dim0;
    }

    data = PyArray_DATA(self);
    if (ilow < ihigh) {
        data += ilow * PyArray_STRIDE(self, 0);
    }

    /* Same shape except dimension 0 */
    shape[0] = ihigh - ilow;
    memcpy(shape+1, PyArray_DIMS(self) + 1,
                        (PyArray_NDIM(self)-1)*sizeof(npy_intp));

    dtype = PyArray_DESCR(self);
    Py_INCREF(dtype);
    ret = (PyArrayObject *)PyArray_NewFromDescr(Py_TYPE(self), dtype,
                             PyArray_NDIM(self), shape,
                             PyArray_STRIDES(self), data,
             PyArray_FLAGS(self) & ~(NPY_ARRAY_MASKNA | NPY_ARRAY_OWNMASKNA),
                             (PyObject *)self);
    if (ret == NULL) {
        return NULL;
    }
    Py_INCREF(self);
    if (PyArray_SetBaseObject(ret, (PyObject *)self) < 0) {
        Py_DECREF(ret);
        return NULL;
    }
    PyArray_UpdateFlags(ret, NPY_ARRAY_UPDATE_ALL);

    /* Also take a view of the NA mask if it exists */
    if (PyArray_HASMASKNA(self)) {
        PyArrayObject_fields *fret = (PyArrayObject_fields *)ret;

        fret->maskna_dtype = PyArray_MASKNA_DTYPE(self);
        Py_INCREF(fret->maskna_dtype);

        data = PyArray_MASKNA_DATA(self);
        if (ilow < ihigh) {
            data += ilow * PyArray_MASKNA_STRIDES(self)[0];
        }
        fret->maskna_data = data;

        memcpy(fret->maskna_strides, PyArray_MASKNA_STRIDES(self),
                        PyArray_NDIM(self) * sizeof(npy_intp));

        /* This view doesn't own the mask */
        fret->flags |= NPY_ARRAY_MASKNA;
        fret->flags &= ~NPY_ARRAY_OWNMASKNA;
    }

    return (PyObject *)ret;
}