在Cython中使用numpy:定义ndarray数据类型/维度

8 投票
2 回答
2573 浏览
提问于 2025-04-16 02:07

我正在尝试写一些Cython代码来处理numpy数组的计算。Cython似乎对我看到的所有示例中用来定义数据类型和维度数量的“[]”不太喜欢。

举个例子,我有一个文件叫test.pyx:

cimport numpy as np
import numpy as np

ctypedef np.ndarray[np.float64_t, ndim=2] mymatrix

cpdef mymatrix hat (mymatrix x):
    a = np.zeros((3,3));
    a[0,1] =  x[2,0];
    a[0,2] = -x[1,0];
    a[1,2] =  x[0,0];
    a[1,0] = -x[2,0];
    a[2,0] =  x[1,0];
    a[2,1] = -x[0,0];
    return a;

我用一个setup.py文件来编译这个,运行命令是“python setup.py build_ext --inplace”。

我得到了以下输出:

running build_ext
cythoning test.pyx to test.c

Error converting Pyrex file to C:
------------------------------------------------------------
...
cimport numpy as np
import numpy as np

ctypedef np.ndarray[np.float64_t, ndim=2] mymatrix
                                         ^
------------------------------------------------------------

test.pyx:4:42: Syntax error in ctypedef statement

<snip, irrelevant>

而如果我去掉“[np.float64_t, ndim=2]”这一部分,它就能正常工作。

有没有人有什么想法?

关于我的系统设置:

操作系统:Windows XP

完整的pythonxy安装,版本是2.6.5.1(目前最新的)

pythonxy据说自带Cython,但我最后还是从这个网站安装了Python 2.6的Cython版本0.12.1:http://www.lfd.uci.edu/~gohlke/pythonlibs/#cython

我怀疑我可能缺少某个路径或者其他东西:我通过明确将numpy头文件目录添加到mingw使用的包含路径中解决了一些问题(见下面的setup.py文件)。

这是我提到的setup.py文件:

from distutils.core import setup
from distutils.extension import Extension
from distutils.sysconfig import get_python_inc
from Cython.Distutils import build_ext
import os.path

inc_base = get_python_inc( plat_specific=1 );
incdir = os.path.join( get_python_inc( plat_specific=1 ), );

#libraries=['math'],
ext_modules = [Extension("test", 
 ["test.pyx"], 
 include_dirs = [
  os.path.join(inc_base,'..\\Lib\\site-packages\\numpy\\core\\include\\numpy'),
  ]
 )
 ]

setup(
  name = 'test',
  cmdclass = {'build_ext': build_ext},
  ext_modules = ext_modules
)

2 个回答

0

我觉得你不能直接这样做:你需要在函数里检查形状和类型。

assert x.shape[0] == 2
assert x.dtype == np.float64

而且只在头部写 cdeftype np.ndarray mymatrix

但是这样你就会失去矩阵值的类型,所以你必须把每个处理过的值都赋值为 float64_t:这样做的效率怎么样呢?

路易斯

3

把类型信息放在函数的声明里,就像这样:

def hat (ndarray[np.float64_t, ndim=2] x):
    a = np.zeros((3,3));
    a[0,1] =  x[2,0];
    etc.

撰写回答