使用 Cython 的布尔 numpy 数组
Boolean numpy arrays with Cython
我有一个 numpy 布尔数组:
myarr = np.array([[False, True], [True, False]])
如果我尝试用它初始化 Cython MemoryView,如下所示:
cdef bint[:,:] mymem = myarr
我收到这个错误:
ValueError: Does not understand character buffer dtype format string ('?')
如果我这样做,效果很好:
cdef np.int_t[:,:] mymem = np.int_(myarr)
如何使用 Cython MemoryViews 存储布尔 numpy 数组?
我 运行 前段时间遇到了同样的问题。不幸的是,我没有找到直接的解决方案。但还有另一种方法:由于布尔值数组的数据类型大小与 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)
输出:
0
2
3
这个信息好像不太好找,my reference 已经很老了(2011 年),但从那以后似乎没有太大变化。
Numpy 的 bool-array 为 False/True 使用 8 位值(这本身并不明显 - C++ 的 std::vector<bool>
例如每个值使用 1 位)和 0
-意思是 False
和 1
-意思是 True
。您可以将 cast=True
用于 unit8
数组,以便将其用作 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
现在:
>>> to_bool_array([True,False,True,False])
array([ True, False, True, False], dtype=bool)
设置 cast=True
给 Cython 的 type-checking 一些松弛,所以 numpy-arrays 具有相同的 element-size (例如 uint8
, int8
和 bool
) 可以重新解释。然而,如果 element-sizes 不同,这将不起作用:例如 np.int8
(1byte) 和 np.int16
(2bytes).
我发现它最简单:
cdef uint8_t[:] arr_memview8 = data.astype(np.uint8)
bool* ptr = <bool*>&arr_memview8[0]
我有一个 numpy 布尔数组:
myarr = np.array([[False, True], [True, False]])
如果我尝试用它初始化 Cython MemoryView,如下所示:
cdef bint[:,:] mymem = myarr
我收到这个错误:
ValueError: Does not understand character buffer dtype format string ('?')
如果我这样做,效果很好:
cdef np.int_t[:,:] mymem = np.int_(myarr)
如何使用 Cython MemoryViews 存储布尔 numpy 数组?
我 运行 前段时间遇到了同样的问题。不幸的是,我没有找到直接的解决方案。但还有另一种方法:由于布尔值数组的数据类型大小与 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)
输出:
0
2
3
这个信息好像不太好找,my reference 已经很老了(2011 年),但从那以后似乎没有太大变化。
Numpy 的 bool-array 为 False/True 使用 8 位值(这本身并不明显 - C++ 的 std::vector<bool>
例如每个值使用 1 位)和 0
-意思是 False
和 1
-意思是 True
。您可以将 cast=True
用于 unit8
数组,以便将其用作 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
现在:
>>> to_bool_array([True,False,True,False])
array([ True, False, True, False], dtype=bool)
设置 cast=True
给 Cython 的 type-checking 一些松弛,所以 numpy-arrays 具有相同的 element-size (例如 uint8
, int8
和 bool
) 可以重新解释。然而,如果 element-sizes 不同,这将不起作用:例如 np.int8
(1byte) 和 np.int16
(2bytes).
我发现它最简单:
cdef uint8_t[:] arr_memview8 = data.astype(np.uint8)
bool* ptr = <bool*>&arr_memview8[0]