簡體   English   中英

如何使用 cython 創建自定義 numpy dtype

[英]How to create a custom numpy dtype using cython

有創建用C定制numpy的dtypes例子在這里

此外, 似乎可以在 cython 中創建自定義 ufunc:

似乎也應該可以使用 cython 創建一個 dtype(然后為其創建自定義 ufunc)。 是否可以? 如果是這樣,你能發布一個例子嗎?

使用案例:

我想做一些生存分析。 基本數據元素是生存時間(浮點數)和相關審查值(假如果相關時間代表失敗時間,真如果它代表審查時間(即,在觀察期間沒有發生故障))。

顯然我可以只使用兩個 numpy 數組來存儲這些值:一個用於時間的浮點數組和一個用於檢查器值的 bool 數組。 但是,我想考慮一個事件多次發生的可能性(這是一個很好的模型,例如,心臟病發作 - 您可以有多個)。 在這種情況下,我需要一個我稱之為MultiEvent的對象數組。 每個MultiEvent包含一系列浮點數(未經審查的故障時間)和一個觀察期(也是一個浮點數)。 請注意,所有MultiEvent的失敗次數並不相同。

我需要能夠對MultiEvent數組執行一些操作:

  1. 獲取每個失敗的次數

  2. 獲取審查時間(即觀察時間減去所有失敗時間的總和)

  3. 根據額外的參數數組(例如危險值數組)計算對數似然。 例如,單個MultiEvent M和恆定危險值h對數似然類似於:

    sum(log(h) + h*t for t in M.times) - h*(M.period - sum(M.times))

其中M.times是故障時間的列表(數組,無論如何), M.period是總觀察期。 我希望應用適當的 numpy 廣播規則,以便我可以:

log_lik = logp(M_vec,h_vec)

只要M_vech_vec的尺寸兼容,它就會起作用。

我當前的實現使用numpy.vectorize 這工作得很好1和2,但實在是太慢了3.另請注意,我不能做這個,因為故障在我的多數據對象的數量是不是提前知道。

Numpy 數組最適合固定大小的數據類型。 如果數組中的對象不是固定大小(例如您的 MultiEvent),則操作會變得更慢。

我建議您將所有生存時間存儲在具有 3 個字段的一維線性記錄數組中:event_id、time、period。 每個事件可以在數組中出現多次:

>>> import numpy as np
>>> rawdata = [(1, 0.4, 4), (1, 0.6, 6), (2,2.6, 6)]
>>> npdata = np.rec.fromrecords(rawdata, names='event_id,time,period')
>>> print npdata
[(1, 0.40000000000000002, 4) (1, 0.59999999999999998, 6) (2, 2.6000000000000001, 6)]

要獲取特定索引的數據,您可以使用花哨的索引:

>>> eventdata = npdata[npdata.event_id==1]
>>> print eventdata
[(1, 0.40000000000000002, 4) (1, 0.59999999999999998, 6)]

這種方法的優點是您可以輕松地將它與基於 ndarray 的函數集成。 您還可以按照手冊中的說明從 cython 訪問此數組:

cdef packed struct Event:
    np.int32_t event_id
    np.float64_t time
    np.float64_6 period

def f():
    cdef np.ndarray[Event] b = np.zeros(10,
        dtype=np.dtype([('event_id', np.int32),
                        ('time', np.float64),
                        ('period', np.float64)]))
    <...>

我很抱歉沒有直接回答這個問題,但我以前也遇到過類似的問題,如果我理解正確的話,您現在遇到的真正問題是您擁有可變長度的數據,這真的,真的不是其中之一numpy 的優勢,這就是您遇到性能問題的原因。 除非您事先知道多事件的最大條目數,否則您會遇到問題,即便如此,對於那些不是多事件的事件,您也會浪費大量充滿零的內存/磁盤空間。

您擁有包含多個字段的數據點,其中一些與其他字段相關,而其中一些需要分組識別。 這強烈暗示您應該考慮某種形式的數據庫來存儲此信息,出於性能、內存、磁盤空間和健全性原因。

對於一個不熟悉你的代碼的人來說,理解一個簡單的數據庫模式比一個復雜的、被黑客攻擊的 numpy 結構要容易得多,后者會令人沮喪地緩慢和臃腫。 相比之下,SQL 查詢編寫起來又快又容易。

根據我對您的解釋的理解,我建議使用 Event 和 MultiEvent 表,其中每個 Event 條目在相關的 MultiEvent 表中都有一個外鍵。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM