14

How can one make empty numpy arrays of type int in Cython? The following works for me for double or float arrays:

# make array of size N of type float
cdef np.ndarray[float, ndim=1] myarr = np.empty(N)
# make array of size N of type int
cdef np.ndarray[int, ndim=1] myarr = np.empty(N)

However, if I try to do the same with int, it fails:

# this fails
cdef np.ndarray[np.int, ndim=1] myarr = np.empty(N)
# wanted to set first element to be an int
myarr[0] = 5

it gives the error:

ValueError: Buffer dtype mismatch, expected 'int' but got 'double'

Since apparently np.empty() returns a double. I tried:

cdef np.ndarray[np.int, ndim=1] myarr = np.empty(N, dtype=int)

but it gives the same error. How can this be done?

2 Answers2

12

Include the statement

cimport numpy as np

and declare the array as, say, np.int32_t:

cdef np.ndarray[np.int32_t, ndim=1] myarr = np.empty(N, dtype=np.int32)

You can drop the 32 from the type declarations, and use

cdef np.ndarray[np.int_t, ndim=1] myarr = np.empty(N, dtype=np.int)

but I prefer to be explicit about the size of the elements in a numpy array.

Note that I also added the dtype to empty; the default dtype of empty is np.float64.

Warren Weckesser
  • 110,654
  • 19
  • 194
  • 214
  • Why doesn't this work with plain `int` or just `np.int` as opposed to `np.int32_t`? –  Apr 23 '13 at 04:19
  • 1
    The type argument of the ndarray declaration needs to be a C type, not a Python object type. If you dig into the numpy cython header file `numpy.pxd`, you'll find that `np.int32_t` ultimately results in the declaration `signed int`. – Warren Weckesser Apr 23 '13 at 04:33
  • could you explain why you use `dtype=np.int` and not `dtype=np.int32_t` when calling `np.empty`? the latter does not work –  Feb 20 '14 at 22:37
1

Wierd!I got the same error when I tried. However, looking at the error message, I just changed the scope of the array creation to a function, and it compiles! I don't know the reason why this is happening, but .

import numpy as np
cimport numpy as np

ctypedef np.int_t DTYPE_t
DTYPE=np.int

def new_array():
    cdef int length = 10
    cdef np.ndarray[DTYPE_t, ndim=1] x = np.zeros([length], dtype=np.int)
    return x

x = new_array()

I think http://docs.cython.org/src/userguide/language_basics.html#python-functions-vs-c-functions has some information related to scoping of python/c/mixed variables.

user1669710
  • 224
  • 1
  • 11