亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

如何將布爾掩碼存儲為 Cython 類的屬性?

如何將布爾掩碼存儲為 Cython 類的屬性?

慕斯王 2022-06-14 17:13:15
我未能將布爾掩碼保存為 Cython 類的屬性。在實際代碼中,我需要這個掩碼來更有效地執行任務。下面是一個示例代碼:核心.pyximport numpy as npcimport numpy as npcdef class MyClass():    cdef public np.uint8_t[:] mask # uint8 has the same data structure of a boolean array    cdef public np.float64_t[:] data    def __init__(self, size):        self.data = np.random.rand(size).astype(np.float64)        self.mask = np.zeros(size, np.uint8)script.pyimport numpy as npimport pyximportpyximport.install(setup_args={'include_dirs': np.get_include()})from core import MyClassmc = MyClass(1000000)mc.mask = np.asarray(mc.data) > 0.5 錯誤當我運行script.py它成功編譯 Cython,但拋出錯誤:Traceback (most recent call last):  File "script.py", line 8, in <module>    mc.mask = np.asarray(mc.data) > 0.5  File "core.pyx", line 6, in core.MyClass.mask.__set__    cdef public np.uint8_t[:] maskValueError: Does not understand character buffer dtype format string ('?')解決方法我目前的解決方法是將掩碼傳遞給我需要的所有函數,cast=True例如:cpdef func(MyClass mc, np.ndarray[np.uint8_t, ndim=1, cast=True] mask):    return np.asarray(mc.data)[mask]問題關于如何將面具存儲在 Cython 類中是否有任何想法?
查看完整描述

2 回答

?
米琪卡哇伊

TA貢獻1998條經驗 獲得超6個贊

所以我不相信內存視圖實際上支持布爾索引。因此,要索引數組,您總是需要做


np.asarray(mc.data)[mask]

# or

mc.data.base[mask] # if you're sure it's always a view of something that supports boolean indexing)

我認為這不會隨著@ead 提到的 Cython 更新而改變。我懷疑這樣做的原因是賦值 ( mc.data[mask] = x) 可能相當容易,但是應該返回什么類型并不明顯mc.data[mask]——它不是內存視圖。


因此,無論您做什么,都會涉及一些混亂的代碼。


對于分配給內存視圖的部分,可以使用


mc.mask = (np.asarray(mc.data) > 0.5).view(np.uint8)

并將其返回到一個 Numpy bool 數組:


np.asarray(mc.mask).view(np.bool)

兩者都不應該涉及復制。


如果是我設計這個,我會保持 memoryviews 非公開(僅供 Cython 使用)并具有僅保存 Python 接口的底層 Numpy 數組的普通對象屬性。您可以使用property使它們保持同步(并進行強制轉換):


cdef class MyClass:

    cdef np.uint8_t[:] mask_mview

    cdef object _mask


    @property

    def mask(self):

        return np.asarray(self._mask).view(np.bool)


    @mask.setter

    def mask(self, value):

        self._mask = value

        self.mask_view = value.view(np.uint8)


    # and the same for data

這樣,您就有了一個 memoryview 可用于 memoryviews 擅長的事情(在 Cython 中逐個元素快速迭代),訪問 Python 的普通 Numpy 數組,并且兩者保持同步(至少通過 Python 接口)。


查看完整回答
反對 回復 2022-06-14
?
慕碼人8056858

TA貢獻1803條經驗 獲得超6個贊

您最好的選擇(如果您不想使用解決方法)可能是等待 Cython 0.29.14 發布。此問題已修復,可能會成為0.29.14的一部分。


以下最小示例


%%cython

import numpy as np

cimport numpy as np

cdef np.uint8_t[:] mask  = np.random.rand(20)>.5

將無法正常導入


ValueError:不理解字符緩沖區 dtype 格式字符串('?')


對于 Cython 0.29.13,但使用github(或 master)上 0.29.x-branch的當前狀態。


查看完整回答
反對 回復 2022-06-14
  • 2 回答
  • 0 關注
  • 125 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號