简体   繁体   English

使用Cython时缺少numpy属性

[英]Missing numpy attribute when using Cython

I have a very simply cython module called empty_test.pyx : 我有一个非常简单的cython模块,名为empty_test.pyx

cimport numpy as cnp


cpdef return_empty():
    return cnp.empty(0, dtype=np.int32)

When I try to run return_empty I get this error: 当我尝试运行return_empty以下错误:

empty_test.pyx:5:14: cimported module has no attribute 'empty'

This is my setup.py file: 这是我的setup.py文件:

from distutils.core import setup
from Cython.Build import cythonize

import numpy as np
setup(
    ext_modules=cythonize(['empty_test.pyx'],
    ),
    include_dirs = [np.get_include()],
)

I'm aware that I could try import numpy as np instead of cimport numpy as np , but I'm trying to use C versions of the numpy code. 我知道我可以尝试import numpy as np而不是cimport numpy as np import numpy as np cimport numpy as np ,但是我正在尝试使用C版本的numpy代码。

Inorder to achieve that, you have to access numpy's C-API directly, which is at least partly wrapped by Cython. 为了实现这一点,您必须直接访问numpy的C-API,它至少部分由Cython包装。 In your case you need PyArray_SimpleNew , which is already cimported with numpy . 在您的情况下,您需要PyArray_SimpleNew ,已经使用numpy导入了它

Thus, your function becomes: 因此,您的功能变为:

%%cython
cimport numpy as cnp

cnp.import_array()  # needed to initialize numpy-API

cpdef return_empty():
    cdef cnp.npy_intp dim = 0
    return cnp.PyArray_SimpleNew(1, &dim, cnp.NPY_INT32)

And now: 现在:

>>> return_empty()
array([], dtype=int32)

Obviously, there is still some Python overhead because of the reference-counting but it is much less, as when using np.empty() : 显然,由于引用计数,仍然存在一些Python开销,但与使用np.empty()时相比,它要少得多:

>>> %timeit return_empty()   
159 ns ± 2.81 ns per loop (mean ± std. dev. of 7 runs, 10000000 loops each)
>>> %timeit return_empty_py
751 ns ± 8.3 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)

Using PyArray_SimpleNew is also faster (about 3 times) than using Cython's array (as considered by you in another question ): 使用PyArray_SimpleNew的速度也比使用Cython array速度快(大约3倍)(正如您在另一个问题中所考虑的那样 ):

%%cython
from cython.view cimport array as cvarray

# shape=(0,) doesn't work
cpdef create_almost_empty_carray():
    return cvarray(shape=(1,), itemsize=sizeof(int), format="i")

and thus: 因此:

>>> %timeit create_almost_empty_carray()
435 ns ± 5.85 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)

Listing of used function return_empty_py : 列出使用的函数return_empty_py

%%cython
cimport numpy as cnp
import numpy as np

cpdef return_empty_py():
    return np.empty(0, np.int32)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM