使用C here创建自定义numpy dtypes的示例:
此外,它seems to be possible在cython中创建自定义ufunc:
似乎也应该可以使用cython创建一个dtype(然后为它创建自定义ufunc)。可能吗?如果是这样,你可以发一个例子吗?
使用案例:
我想做一些生存分析。基本数据元素是具有相关审查值的生存时间(浮点数)(如果关联时间表示失败时间,则为False;如果相反表示审查时间,则为True)(即,在观察期间未发生故障)。
显然,我可以使用两个numpy数组来存储这些值:时间的float数组和censor值的bool数组。但是,我想说明事件发生多次的可能性(这是一个很好的模型,比如心脏病发作 - 你可以拥有多个)。在这种情况下,我需要一个对象数组,我称之为MultiEvent
。每个MultiEvent
包含一系列浮点数(未经审查的失败时间)和一个观察期(也是一个浮点数)。请注意,所有MultiEvent
的失败次数并不相同。
我需要能够对MultiEvent
s:
获取每个
获取审查时间(即观察时间减去所有失败时间的总和)
根据其他参数数组(例如危险值数组)计算对数似然。例如,单个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_vec
和h_vec
的尺寸兼容,它就会有效。
我目前的实施使用numpy.vectorize
。这对于1和2来说效果很好,但它对于3来说太慢了。还要注意我不能做this因为我的MultiData对象中的失败次数未提前知道。
答案 0 :(得分:1)
Numpy数组最适合具有固定大小的数据类型。如果数组中的对象不是固定大小(例如MultiEvent),则操作会变慢。
我建议你将所有生存时间存储在一个包含3个字段的1d线性记录数组中: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的函数集成。您也可以按照manual:
中的说明从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)]))
<...>
答案 1 :(得分:0)
我为没有直接回答这个问题而道歉,但我之前遇到过类似的问题,如果我理解正确的话,你现在遇到的真正问题是你有可变长度的数据,这真的,真的不是numpy的优点之一,也是你遇到性能问题的原因。除非您事先知道多个事件的最大条目数,否则您将遇到问题,即使这样,您也会浪费大量内存/磁盘空间来填充那些非多事件事件的零。
您的数据点包含多个字段,其中一些字段与其他字段相关,其中一些字段需要在组中进行标识。这强烈暗示您应该考虑使用某种形式的数据库来存储此信息,包括性能,内存,磁盘空间和理智原因。
对于一个刚接触您的代码的人来说,理解一个简单的数据库模式要比一个复杂的,黑客攻击的结构更加容易,这种结构会令人沮丧地缓慢而臃肿。相比之下,SQL查询可以快速轻松地编写。
我建议根据我对你的解释使用Event和MultiEvent表的理解,其中每个Event条目都有一个外键进入MultiEvent表中。