如何在Cython中声明numpy.bool?

3
根据官方文档:http://docs.cython.org/en/latest/src/tutorial/numpy.html,我们应该“ctypedef”一个相应的编译时类型,但我尝试了几种方法来处理numpy.bool,仍然出现错误。 1.
DTYPE2 = np.bool

ctypedef np.bool_t DTYPE2_t

抛出异常:'bool_t' 不是一个类型标识符

2.

DTYPE2 = np.bint

ctypedef np.bint_t DTYPE2_t

raise:“bint_t”不是类型标识符

3. 在.pyx文件的顶部添加:

from libcpp cimport bool
#? As recommended by McKelvin in  [https://dev59.com/HWAf5IYBdhLWcg3wbSQh][2]
#from libcpp cimport bool_t 
from libcpp.vector cimport vector

没什么帮助!

4. 我看到了这篇文章: 在Cython中声明numpy布尔掩码 但是我需要在函数参数中定义变量,以便传递一个numpy.bool数组。

def Func(np.ndarray[np.bool_t, ndim=1] f)

## def Func(np.ndarray[np.bool, ndim=1] f)

错误: 无效的类型

5. 忽略声明吗?根据官方文档,如果我想加快函数的速度,似乎在函数的参数中需要声明:

def naive_convolve(np.ndarray[**DTYPE_t**, ndim=2] f, np.ndarray[DTYPE_t, ndim=2] g):

那么我应该如何处理numpy.bool呢?

我的测试基于以下简单的代码:

import numpy as np
cimport numpy as np
cimport cython

DTYPE2 = np.bint
ctypedef np.bint_t DTYPE2_t
def Func(np.ndarray[DTYPE2_t, ndim=1] npdata):
    print(npdata)

cython:最新版本

windows7 操作系统

我确定 cython 已经正确安装。当没有 np.bool 时,它可以正常工作。

1个回答

7
numpy布尔类型的名称是 npy_bool。因此,您的测试代码的正确版本应该是:
import numpy as np
cimport numpy as np
cimport cython

def Func(np.ndarray[np.npy_bool, ndim=1, cast=True] npdata):
    print(npdata)
    return npdata

注意上面的cast=True(我也加了一个返回语句进行测试)。这里是一些测试Func的代码:
arr = np.random.randint(0,2, size=3, dtype=int)
boolArr = np.array(arr, dtype=bool)

# Func(arr)                     # raises "ValueError: Item size of buffer (8 bytes) does not match size of 'npy_bool' (1 byte)"
returnArr = Func(boolArr)
assert returnArr.dtype is np.dtype(bool)

关于 cast 的注意事项

如果没有使用 cast 关键字,在尝试调用 Func 时会出现一个非常奇怪的错误信息:

ValueError: Does not understand character buffer dtype format string ('?')

深入Cython源代码可以对上述ValueError有一些了解。Numpy使用的dtypes表示之一是"array-protocol type strings"。布尔值的类型字符串是'?'。许多这样的类型可以使用数字指定,例如'4i',它表示该类型的单个元素需要多少字节。Cython显然根据此字符串解释数组类型,并期望有一个数字, 但似乎Numpy没有为布尔值提供数字。可能只是某个地方(在Numpy或Cython中)需要修复错误。 <代码>cast=True参数可能不再需要太久了。我已经提交了一个修复Cython的拉取请求,它似乎正在通过审查流程中。

太好了!非常感谢!这就是我想要的。 - Stone
有趣。这个 bug 还在!感谢您写下了详细的解释。 - Ginger
1
@Ginger 我刚刚提交了一个Cython修复的PR,希望这个bug很快就会被解决。 - tel
非常好的答案,谢谢!您知道如何通过 memoryview 访问这个数组吗? - colelemonz

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