python - Numpy->Cython 转换 : Compile error:Cannot convert 'npy_intp *' to Python object

标签 python numpy scipy python-2.7 cython

我有以下代码可以正确转换为 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:

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

但是当我编译时我得到:

$ 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 中使用列表的正确方法:

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

编辑:

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

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'

我绑定(bind)了这两个选项:

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 ...

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

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

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

$ 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’

它还会继续枚举所有其他类型。

然后是告诉我这个:

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 的调用是:

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”是什么数据类型?

最佳答案

我认为元组解包在 Cython 中的工作方式与在 Python 中不同。您必须使用 (board.shape[0], board.shape[1]) 指定 checked 的大小。

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

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

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 中的相同操作快。

更新 1:

我认为这些错误是因为编译器找不到 NumPy 头文件。更新您的 setup.py 以包含这些文件的路径。该路径应由 np.get_include() 函数输出。

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

我不确定“参数过多”错误是怎么回事。如果您从 Python 中调用该函数,则需要将其声明为 defcpdef。使用 cdef 声明的函数只能从 Cython 调用。这是描述here在 Cython 文档中。

关于python - Numpy->Cython 转换 : Compile error:Cannot convert 'npy_intp *' to Python object,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9452427/

相关文章:

python - 在Python中求切比雪夫多项式的根

scipy - 无法为通过 pycall 在 julia 中导入的 scipy rbf 分配自定义径向?

python - 在Python中处理列表和消息

python - 在Python中的同一个图上绘制数组列表?

python - 我如何从 __init__ 调用属性 setter

python - Cython:(为什么/何时)最好使用 Py_ssize_t 进行索引?

python - 训练岭回归的 alpha 值

python - 使用稀疏矩阵与 sklearn 亲和性传播

python - 返回给定短语的匹配列表

python - user_login_failed 信号的 Django 日志用户 IP