我以面向对象的风格实现了纯Python代码。在某些方法中存在时间密集型循环,我希望通过对代码进行 cythonizing 来加快速度。
我使用了大量 numpy 数组,并且很难将类转换为 Cython 扩展类型。
这里我声明两个 numpy 数组“verteces”和“norms”作为属性:
将 numpy 导入为 np c将 numpy 导入为 np
cdef class Geometry(object):
cdef:
np.ndarray verteces
np.ndarray norms
def __init__(self, config):
""" Initialization"""
self.config = config
self.verteces = np.empty([1,3,3],dtype=np.float32)
self.norms = np.empty(3,dtype=np.float32)
Run Code Online (Sandbox Code Playgroud)
在运行时,将定义数组的实际大小。调用Geometry.load()同一个类的方法时会发生这种情况。该方法打开一个 STL 文件并循环遍历三角形条目。
最后我想确定三角形和射线的交点。在相应的方法中,我使用以下声明。
cdef void hit(self, object photon):
""" Ray-triangle intersection according to Moeller and Trumbore algorithm """
cdef:
np.ndarray[DTYPE_t, ndim=3] verteces = self.verteces # nx3x3
np.ndarray[DTYPE_t, ndim=2] norms = self.norms
np.ndarray[DTYPE_t, ndim=1] ph_dir = photon.direction
np.ndarray[DTYPE_t, ndim=1] ph_origin = photon.origin
np.ndarray[DTYPE_t, ndim=1] v0, v1, v2, vec1, vec2, trsc, norm, v, p_inter
float a, b, par, q, q0, q1, s0, s1
int i_tri
Run Code Online (Sandbox Code Playgroud)
当我尝试编译此代码时,我收到以下错误消息:
'dimensions' is not a member of 'tagPyArrayObject'
Run Code Online (Sandbox Code Playgroud)

我不是很熟悉 cython 编程,但也许错误是因为我必须在 C 扩展类型中初始化固定大小的数组?然而,在读取 STL 文件之前,数组的大小是未知的。
小智 7
不确定这是否与您的问题有关,但在我的 setup.py 文件中指定“NPY_1_7_API_VERSION”宏时,我收到了相同的错误消息。
extension_module = Extension(
'yourfilename',
sources=["yourfilename.pyx],
include_dirs=[numpy.get_include()],
define_macros=[("NPY_NO_DEPRECATED_API", "NPY_1_7_API_VERSION")],
)
Run Code Online (Sandbox Code Playgroud)
使用这个宏,一个简单的npmatrix.shape[0]numpy 函数被编译为:
/* "yourfilename.pyx":35
*
* cpdef int vcount(self):
* return self.npmatrix.shape[0]
*
*/
__pyx_r = (__pyx_v_self->npmatrix->dimensions[0]);
Run Code Online (Sandbox Code Playgroud)
这会导致错误。只需删除宏就解决了我的这个错误。