Cython布尔numpy数组

Sam*_*adi 4 python numpy cython memoryview typed-memory-views

我有一个numpy的布尔数组:

myarr = np.array([[False, True], [True, False]])
Run Code Online (Sandbox Code Playgroud)

如果我尝试使用它初始化Cython MemoryView,如下所示:

cdef bint[:,:] mymem = myarr
Run Code Online (Sandbox Code Playgroud)

我收到此错误:

ValueError: Does not understand character buffer dtype format string ('?')
Run Code Online (Sandbox Code Playgroud)

如果我改为这样做,则可以正常工作:

cdef np.int_t[:,:] mymem = np.int_(myarr)
Run Code Online (Sandbox Code Playgroud)

如何使用Cython MemoryViews存储布尔型numpy数组?

Pad*_*Key 6

我前段时间遇到了同样的问题。不幸的是我没有找到直接的解决方案。但还有另一种方法:由于布尔值数组具有与 相同的数据类型大小uint8,因此您也可以使用此类型的内存视图。内存视图中的值uint8也可以与布尔值进行比较,因此行为基本上与实际bint内存视图相同:

cimport cython
cimport numpy as np
import numpy as np
ctypedef np.uint8_t uint8

cdef int i
cdef np.ndarray array = np.array([True,False,True,True,False], dtype=bool)
cdef uint8[:] view = np.frombuffer(array, dtype=np.uint8)
for i in range(view.shape[0]):
    if view[i] == True:
        print(i)
Run Code Online (Sandbox Code Playgroud)

输出:

0
2
3
Run Code Online (Sandbox Code Playgroud)


ead*_*ead 5

这些信息似乎不容易找到,我的参考文献还很旧(2011年),但此后似乎没有太大变化。

Numpy的布尔数组使用False / True的8位值(这本身并不明显-C ++ std::vector<bool>使用每个值1位),其0含义为-意义False1-含义True。您可以使用cast=True一个unit8为了-array使用它作为一个bool-阵列,例如:

 %%cython
 import numpy as np
 cimport numpy as np
 def to_bool_array(lst):
    cdef np.ndarray[np.uint8_t, ndim = 1, cast=True] res
    res=np.array(lst, dtype=bool)
    return res
Run Code Online (Sandbox Code Playgroud)

现在:

 >>> to_bool_array([True,False,True,False])
 array([ True, False,  True, False], dtype=bool)
Run Code Online (Sandbox Code Playgroud)

设置cast=True给出了一些松弛以用Cython的类型检查,所以用相同的元件尺寸的numpy的阵列(例如uint8int8bool)可以被重新解释。但是,如果元素大小不同(例如np.int8(1字节)和np.int16(2 字节)),这将无法工作。