如何在Cython中将一个字符串类型的numpy数组传递给函数

20

传递一个np.float64_t数据类型的numpy数组是可以正常工作的(如下),但我不能传递字符串数组。

以下是有效的代码示例:

# cython_testing.pyx
import numpy as np
cimport numpy as np

ctypedef np.float64_t dtype_t 

cdef func1 (np.ndarray[dtype_t, ndim=2] A):
    print A 

def testing():
    chunk = np.array ( [[94.,3.],[44.,4.]], dtype=np.float64)

    func1 (chunk)

但是我无法使其工作: 我找不到适配NumPy字符串数据类型的匹配“类型标识符”。

# cython_testing.pyx
import numpy as np
cimport numpy as np

ctypedef np.string_t dtype_str_t 

cdef func1 (np.ndarray[dtype_str_t, ndim=2] A):
    print A 

def testing():
    chunk = np.array ( [['huh','yea'],['swell','ray']], dtype=np.string_)

    func1 (chunk)

编译错误为:

Error compiling Cython file:
------------------------------------------------------------
ctypedef np.string_t dtype_str_t 
    ^
------------------------------------------------------------

cython_testing.pyx:9:9: 'string_t' is not a type identifier

更新

经过查看 numpy.pxd,我看到以下 ctypedef 语句。也许这已经足够说明我可以使用 uint8_t 并且假装一切正常,只要我能进行一些强制类型转换?

ctypedef unsigned char      npy_uint8
ctypedef npy_uint8      uint8_t

只需看看转换的代价有多高。

2个回答

9
使用Cython 0.20.1时,可以使用 cdef np.ndarray ,而不需要指定数据类型和维度数量:
import numpy as np
cimport numpy as np

cdef func1(np.ndarray A):
    print A

def testing():
    chunk = np.array([['huh','yea'], ['swell','ray']])
    func1(chunk)

@TedPetrou 我正在尝试构建一个示例,在其中使用 dtype=object 可以加速更新答案,但到目前为止我发现它等同于不指定 dtype。您是如何测量100倍的加速值的? - Saullo G. P. Castro
在我之前的评论中,似乎我说错了话。改用对象后,看起来我的性能提高了5倍。请使用这个数组:a = np.array(['some', 'strings', 'in', 'an', 'array'] * 10 ** 5) - Ted Petrou

7

谢谢。我已经为你的答案点赞了。虽然我希望可以通过使用Numpy结构化数组[http://docs.scipy.org/doc/numpy/user/basics.rec.html#structured-arrays]来解决问题,但我仍在寻找如何传递其中之一的方法。 - HeyWatchThis
1
至少对于我的目的来说,在Cython中使用cProfile,似乎仍然可以在不进行类型标注的情况下传递Numpy数组。但是,您将无法获得readthedocs.org参考文档中描述的Cython优化。 - HeyWatchThis
1
尽管能够慢慢地使用它们仍然比完全不能使用要好,对吧? - JAB
此链接的内容已被修改。该引用不存在。 - gzc

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接