Numpy-> Cython转换:编译错误:无法将'npy_intp *'转换为Python对象 [英] Numpy->Cython conversion: Compile error:Cannot convert 'npy_intp *' to Python object

查看:129
本文介绍了Numpy-> Cython转换:编译错误:无法将'npy_intp *'转换为Python对象的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有以下代码要正确转换为cython:

I have the following code that is to be propperly converted to cython:

from numpy import *

## returns winning players or [] if undecided. 
def score(board):
    scores = []
    checked = zeros(board.shape)
    for i in xrange(len(board)):
        for j in xrange(len(board)):
            if checked[i,j] == 0 and board[i,j] !=0:
                ... do stuf

我尝试转换为cython:

my attempt at conversion to cython:

import numpy as np
cimport numpy as np

@cython.boundscheck(False)
@cython.wraparound(False)
@cython.nonecheck(False)

## returns winning players or [] if undecided. 
def score(np.ndarray[int, ndim=2] board):
    scores = []
    cdef np.ndarray[int, ndim = 2 ] checked
    checked = np.zeros(board.shape)
    for i in xrange(len(board)):
        for j in xrange(len(board)):
            if checked[i,j] == 0 and board[i,j] !=0:
                ... do stuf

但是当我编译时我得到了:

But when I compile I get :

$ python setup.py build_ext --inplace
running build_ext
cythoning newgox.pyx to newgox.c


## returns winning players or [] if undecided. 
def score(np.ndarray[int, ndim=2] board):
    scores = []
    cdef np.ndarray[int, ndim = 2 ] checked
    checked = np.zeros(board.shape)
                       ^
------------------------------------------------------------

newgox.pyx:58:28: Cannot convert 'npy_intp *' to Python object 
building 'newgox' extension

此外,我不确定这是处理cython中列表的正确方法:

Also, I'm not sure this is the right way to work with lists in cython:

scores = []
if some_stuff_is_true:
    scores.append(some_integer)

谢谢,代码现在可以编译了,但是当我运行它时,我得到了错误:

Thanks, the code now compiles but when I run it I get the error:

File "newgox.pyx", line 63, in newgox.score (newgox.c:1710)
    def score(np.ndarray[np.int, ndim=2] board):
ValueError: Buffer dtype mismatch, expected 'int object' but got 'long'

我绑定了这两个选项:

ctypedef np.int_t DTYPE_t
DTYPE = np.int

,然后继续:

board = zeros((5,5), dtype = DTYPE)
def score(np.ndarray[DTYPE, ndim=2] board):

或仅在两个声明中:

    ...  np.int ...

这将导致相同的错误,但带有签名:

This results in the same error, but with signature:

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


感谢bellamyj,但建议的代码无法编译


Thanks bellamyj, but your suggested code won't compile,

$ python setup.py build_ext --inplace
running build_ext
cythoning newgox.pyx to newgox.c
building 'newgox' extension
gcc-4.2 -fno-strict-aliasing -fno-common -dynamic -arch i386 -arch x86_64 -g -O2 -DNDEBUG -g -O3 -I/Library/Frameworks/Python.framework/Versions/2.7/include/python2.7 -c newgox.c -o   build/temp.macosx-10.6-intel-2.7/newgox.o

newgox.c:238:31: error: numpy/arrayobject.h: No such file or directory
newgox.c:239:31: error: numpy/ufuncobject.h: No such file or directory
newgox.c:356: error: expected ‘=’, ‘,’, ‘;’, ‘asm’ or ‘__attribute__’ before ‘__pyx_t_5numpy_int8_t’
newgox.c:365: error: expected ‘=’, ‘,’, ‘;’, ‘asm’ or ‘__attribute__’ before ‘__pyx_t_5numpy_int16_t’
newgox.c:374: error: expected ‘=’, ‘,’, ‘;’, ‘asm’ or ‘__attribute__’ before ‘__pyx_t_5numpy_int32_t’

它还将继续枚举所有其他类型.

And it continues to enumerate all other types as well.

然后告诉我:

newgox.c:978: error: expected ‘)’ before ‘*’ token
newgox.c:979: error: expected ‘)’ before ‘*’ token
newgox.c:980: error: expected ‘)’ before ‘*’ token
newgox.c:983: error: expected declaration specifiers or ‘...’ before ‘PyArrayObject’
newgox.c:984: error: expected declaration specifiers or ‘...’ before ‘PyArrayObject’
newgox.c:985: error: expected ‘)’ before ‘*’ token
newgox.c:987: error: ‘__pyx_t_5numpy_int32_t’ undeclared here (not in a function)
newgox.c: In function ‘__pyx_pf_6newgox_7score’:
newgox.c:1638: error: ‘PyArrayObject’ undeclared (first use in this function)
newgox.c:1638: error: (Each undeclared identifier is reported only once
newgox.c:1638: error: for each function it appears in.)
newgox.c:1638: error: ‘__pyx_v_checked’ undeclared (first use in this function)
newgox.c:1659: error: ‘__pyx_t_5’ undeclared (first use in this function)
newgox.c:1721: error: expected expression before ‘)’ token
newgox.c:1723: error: expected expression before ‘)’ token
newgox.c:1747: error: expected expression before ‘)’ token
newgox.c:1766: error: expected expression before ‘)’ token
newgox.c:1813: error: expected expression before ‘)’ token
newgox.c:1846: error: expected expression before ‘)’ token
newgox.c:1846: error: too many arguments to function ‘__pyx_f_6newgox_check_life’
newgox.c:2009: error: expected expression before ‘)’ token
newgox.c:2009: warning: assignment makes pointer from integer without a cast
newgox.c:2012: error: expected expression before ‘)’ token
newgox.c:2032: error: expected expression before ‘)’ token
newgox.c: At top level:
newgox.c:2088: error: expected declaration specifiers or ‘...’ before ‘PyArrayObject’
newgox.c: In function ‘__pyx_f_6newgox_check_life’:
newgox.c:2124: error: ‘__pyx_v_board’ undeclared (first use in this function)
newgox.c:2160: error: ‘PyArrayObject’ undeclared (first use in this function)
newgox.c:2160: error: expected expression before ‘)’ token
newgox.c:2160: error: too many arguments to function ‘__pyx_f_6newgox_liberty’
newgox.c:2420: error: too many arguments to function ‘__pyx_f_6newgox_check_life’
newgox.c: At top level:
newgox.c:2583: error: expected declaration specifiers or ‘...’ before ‘PyArrayObject’
newgox.c: In function ‘__pyx_f_6newgox_liberty’:
newgox.c:2610: error: ‘__pyx_v_board’ undeclared (first use in this function)
newgox.c: At top level:
newgox.c:2859: error: expected ‘)’ before ‘*’ token
newgox.c: In function ‘__pyx_pf_5numpy_7ndarray___getbuffer__’:
newgox.c:2999: error: ‘PyArray_Descr’ undeclared (first use in this function)
newgox.c:2999: error: ‘__pyx_v_descr’ undeclared (first use in this function)
newgox.c:3062: error: ‘PyArrayObject’ undeclared (first use in this function)
newgox.c:3062: error: expected expression before ‘)’ token
newgox.c:3071: error: ‘npy_intp’ undeclared (first use in this function)
newgox.c:3114: error: expected expression before ‘)’ token
newgox.c:3114: error: ‘NPY_C_CONTIGUOUS’ undeclared (first use in this function)
newgox.c:3154: error: expected expression before ‘)’ token
newgox.c:3154: error: ‘NPY_F_CONTIGUOUS’ undeclared (first use in this function)
newgox.c:3184: error: expected expression before ‘)’ token
newgox.c:3184: warning: assignment makes pointer from integer without a cast
newgox.c:3240: error: expected expression before ‘)’ token
newgox.c:3240: error: subscripted value is neither array nor pointer
newgox.c:3249: error: expected expression before ‘)’ token
newgox.c:3249: error: subscripted value is neither array nor pointer
newgox.c:3262: error: expected expression before ‘)’ token
newgox.c:3271: error: expected expression before ‘)’ token
newgox.c:3291: error: expected expression before ‘)’ token

还有更多

请注意:

newgox.c:2160: error: too many arguments to function ‘__pyx_f_6newgox_liberty’
newgox.c:2420: error: too many arguments to function ‘__pyx_f_6newgox_check_life’

但是我从score/1到check_life的电话是:

But my call from score/1 to check_life is:

life, newly_checked = check_life(i,j,board,[])

它是这样收到的:

# helper functions of score/1
cdef check_life(int i, int j, np.ndarray[int, ndim=2] board, checked):
    ...
    return life, checked

最后,您使用的"i4"是哪种数据类型?

Finally, what kind of data type is the "i4" that you use?

推荐答案

我不认为在Cython中像在Python中那样进行元组拆包是可行的.您必须使用(board.shape[0], board.shape[1])指定checked的大小.

I don't think tuple unpacking works in Cython like it does in Python. You have to specify the size of checked using (board.shape[0], board.shape[1]).

您还需要指定checked的数据类型.默认情况下,np.zeros返回float64.您需要将其更改为int32以与声明的类型兼容.

You also need to specify the datatype of checked. By default np.zeros returns a float64. You need to change that to an int32 to be compatible with the declared type.

这是应该运行的修改版本.

Here's a modified version that should run.

def score(np.ndarray[int, ndim=2] board):

    cdef np.ndarray[np.int32_t, ndim = 2] checked
    checked = np.zeros((board.shape[0], board.shape[1]), dtype='i4')

    for i in xrange(len(board)):
        for j in xrange(len(board)):
            if checked[i,j] == 0 and board[i,j] !=0:
                ... do stuff

要回答问题的第二部分-是的,您可以在Cython函数内追加列表.但是,据我了解,这涉及Python函数调用,因此它不会比Python中的相同操作快.

To answer the second part of your question - yes you can append to lists within Cython functions. However, as I understand it this involves Python function calls, so it won't be any faster than the same operations within Python.

更新1:

我相信这些错误是因为编译器找不到NumPy头文件.更新您的setup.py以包括这些文件的路径.路径应通过np.get_include()函数输出.

I believe those errors are because the compiler can't find the NumPy header files. Update your setup.py to include the path to those files. The path should be output by the np.get_include() function.

import numpy as np
from distutils.core import setup
from distutils.extension import Extension
from Cython.Distutils import build_ext

setup(
      cmdclass={'build_ext': build_ext},
      ext_modules = [
              Extension("new_gox",
                        ["new_gox.pyx"],
                        include_dirs=[np.get_include()])
                    ]
     )

dtype i4是一个32位整数.等效于np.int32.

The dtype i4 is a 32 bit integer. It's equivalent to np.int32.

我不确定参数过多"错误是怎么回事.如果要从Python内部调用该函数,则需要将其声明为defcpdef.用cdef声明的函数只能从Cython中调用.在Cython中的此处中对此进行了描述文档.

I'm not sure what's going on with the 'too many arguments' errors. If you're calling that function from within Python, it needs to be declared as either def or cpdef. Functions declared with cdef can only be called from Cython. This is described here in the Cython docs.

这篇关于Numpy-> Cython转换:编译错误:无法将'npy_intp *'转换为Python对象的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆