2016-02-29 185 views
2

我是新来的cython,并且我一直有一个重复出现的问题,涉及在numpy数组中编码unicode。Cython:将Unicode存储在numpy数组中

这里的问题的一个例子:

import numpy as np 
cimport numpy as np 

cpdef pass_array(np.ndarray[ndim=1,dtype=np.unicode] a): 
    pass 

cpdef access_unicode_item(np.ndarray a): 
    cdef unicode item = a[0] 

实例错误:

In [3]: unicode_array = np.array([u"array",u"of",u"unicode"],dtype=np.unicode) 

In [4]: pass_array(unicode_array) 
ValueError: Does not understand character buffer dtype format string ('w') 

In [5]: access_item(unicode_array) 
TypeError: Expected unicode, got numpy.unicode_ 

的问题似乎是,该值是不是真正的unicode的,而是numpy.unicode_。有没有办法将数组中的值编码为适当的unicode(以便我可以输入用于cython代码的单个项目)?

+0

如果您想在您的Cython代码中使用Python'unicode'对象,最简单的方法就是给Numpy数组一个'object' dtype。如果你想保留一个固定长度的Unicode数组,可能在某种程度上你可以在必要时使用[PyUnicode_FromUnicode](https://docs.python.org/3/c-api/unicode.html#c.PyUnicode_FromUnicode)? – 2016-03-01 14:12:12

回答

1

在Py2.7

In [375]: arr=np.array([u"array",u"of",u"unicode"],dtype=np.unicode) 

In [376]: arr 
Out[376]: 
array([u'array', u'of', u'unicode'], 
     dtype='<U7') 

In [377]: arr.dtype 
Out[377]: dtype('<U7') 

In [378]: type(arr[0]) 
Out[378]: numpy.unicode_ 

In [379]: type(arr[0].item()) 
Out[379]: unicode 

一般而言x[0]在numpy的子类返回x的元件。在这种情况下,np.unicode_unicode的一个子类。

In [384]: isinstance(arr[0],np.unicode_) 
Out[384]: True 

In [385]: isinstance(arr[0],unicode) 
Out[385]: True 

我想你会遇到同样的问题np.int32int之间。但我没有足够的工作与cython确定。


你在哪里看过cython指定字符串(Unicode或字节)dtype的代码?

http://docs.cython.org/src/tutorial/numpy.html具有像

# We now need to fix a datatype for our arrays. I've used the variable 
# DTYPE for this, which is assigned to the usual NumPy runtime 
# type info object. 
DTYPE = np.int 
# "ctypedef" assigns a corresponding compile-time type to DTYPE_t. For 
# every type in the numpy module there's a corresponding compile-time 
# type with a _t-suffix. 
ctypedef np.int_t DTYPE_t 
.... 
def naive_convolve(np.ndarray[DTYPE_t, ndim=2] f): 

[]部分的目的是为了提高索引效率表达式。

我们需要做的就是输入ndarray对象的内容。我们用一个必须告诉数据类型(第一个参数)和维数(“ndim”只有关键字参数,如果没有提供则假设一维)的特殊“缓冲”语法来做到这一点。

我不认为np.unicode会有帮助,因为它没有指定字符长度。完整的字符串dtype必须包含字符的数量,例如。在我的例子中为<U7

我们需要找到传递字符串数组的工作示例 - 无论是在cython文档还是其他SO cython问题。


对于某些操作,你可以把Unicode的阵列作为int32数组。

In [397]: arr.nbytes 
Out[397]: 84 

3串x 7的字符/串* 4字节/字符

In [398]: arr.view(np.int32).reshape(-1,7) 
Out[398]: 
array([[ 97, 114, 114, 97, 121, 0, 0], 
     [111, 102, 0, 0, 0, 0, 0], 
     [117, 110, 105, 99, 111, 100, 101]]) 

用Cython给你最大速度提高时,你可以绕过Python函数和方法。这将包括绕过大部分Python字符串和unicode功能。