Ihm*_*ahr 11 python numpy cython scipy python-2.7
我有以下代码,适当地转换为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
Run Code Online (Sandbox Code Playgroud)
我尝试转换为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
Run Code Online (Sandbox Code Playgroud)
但是当我编译时,我得到:
$ 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
Run Code Online (Sandbox Code Playgroud)
另外,我不确定这是在cython中使用列表的正确方法:
scores = []
if some_stuff_is_true:
scores.append(some_integer)
Run Code Online (Sandbox Code Playgroud)
编辑:
谢谢,代码现在编译但是当我运行它时我收到错误:
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'
Run Code Online (Sandbox Code Playgroud)
我把这两个选项联系起来:
ctypedef np.int_t DTYPE_t
DTYPE = np.int
Run Code Online (Sandbox Code Playgroud)
然后继续:
board = zeros((5,5), dtype = DTYPE)
def score(np.ndarray[DTYPE, ndim=2] board):
Run Code Online (Sandbox Code Playgroud)
或者只是在两个声明中:
... np.int ...
Run Code Online (Sandbox Code Playgroud)
这导致相同的错误,但签名:
ValueError: Buffer dtype mismatch, expected 'int' but got 'long'
Run Code Online (Sandbox Code Playgroud)
谢谢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’
Run Code Online (Sandbox Code Playgroud)
它继续列举所有其他类型.
然后告诉我这个:
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
Run Code Online (Sandbox Code Playgroud)
还有一些.
注意它说:
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’
Run Code Online (Sandbox Code Playgroud)
但我从得分/ 1到check_life的电话是:
life, newly_checked = check_life(i,j,board,[])
Run Code Online (Sandbox Code Playgroud)
收到这样的:
# helper functions of score/1
cdef check_life(int i, int j, np.ndarray[int, ndim=2] board, checked):
...
return life, checked
Run Code Online (Sandbox Code Playgroud)
最后,您使用的"i4"是什么类型的数据?
jos*_*ers 15
我不认为元组解包在Cython中像在Python中那样工作.你必须指定的大小checked使用(board.shape[0], board.shape[1]).
您还需要指定数据类型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
Run Code Online (Sandbox Code Playgroud)
要回答问题的第二部分 - 是的,您可以附加到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()])
]
)
Run Code Online (Sandbox Code Playgroud)
dtype i4是32位整数.它相当于np.int32.
我不确定"太多参数"错误会发生什么.如果您在Python中调用该函数,则需要将其声明为def或cpdef.声明的函数cdef只能从Cython中调用.这说明这里在用Cython文档.
| 归档时间: |
|
| 查看次数: |
6934 次 |
| 最近记录: |