Cython:将unicode存储在numpy数组中

时间:2016-02-29 11:17:49

标签: numpy unicode cython

我是cython的新手,我一直有一个重新出现的问题,涉及在numpy数组中编码unicode。

以下是问题的一个示例:

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代码中使用)?

1 个答案:

答案 0 :(得分: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或byte)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]])

当您可以绕过Python函数和方法时,Cython可以为您提供最快的速度提升。这将包括绕过大部分Python字符串和unicode功能。