【问题标题】:Boolean numpy arrays with Cython带有 Cython 的布尔 numpy 数组
【发布时间】:2018-08-10 00:33:02
【问题描述】:

我有一个 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 数组?

【问题讨论】:

    标签: python numpy cython memoryview typed-memory-views


    【解决方案1】:

    我发现这样做最简单:

    cdef uint8_t[:] arr_memview8 = data.astype(np.uint8)
    bool* ptr = <bool*>&arr_memview8[0]
    

    【讨论】:

      【解决方案2】:

      这个信息似乎不容易找到,my reference 已经很老了(2011 年),但从那时起似乎没有太大变化。

      Numpy 的布尔数组对 False/True 使用 8 位值(这本身并不明显 - C++ 的 std::vector&lt;bool&gt; 使用例如每个值 1 位)与 0-意思是 False1-意思是True。您可以将cast=True 用于unit8-array,以便将其用作bool-array,例如:

       %%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 的类型检查有些松懈,因此可以重新解释具有相同元素大小的numpy 数组(例如uint8int8bool)。但是,如果元素大小不同,这将不起作用:例如 np.int8(1byte) 和 np.int16 (2bytes)。

      【讨论】:

        【解决方案3】:

        前段时间我遇到了同样的问题。不幸的是,我没有找到直接的解决方案。但是还有另一种方法:由于布尔值数组的数据类型大小与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
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2017-08-06
          • 2017-01-01
          • 2020-04-23
          • 2016-12-08
          • 2016-03-11
          • 1970-01-01
          • 1970-01-01
          • 2017-09-24
          相关资源
          最近更新 更多